• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb-js / mongodb-mcp-server / 25330180826

04 May 2026 04:23PM UTC coverage: 82.039%. First build
25330180826

Pull #1120

github

web-flow
Merge 2c96aab9e into 83cc14597
Pull Request #1120: feat: MCP Cluster upgrade tool CLOUDP-397237

1771 of 2389 branches covered (74.13%)

Branch coverage included in aggregate %.

66 of 73 new or added lines in 3 files covered. (90.41%)

3258 of 3741 relevant lines covered (87.09%)

170.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.02
/src/common/atlas/apiClient.ts
1
import createClient from "openapi-fetch";
2
import type { ClientOptions, FetchOptions, Client, Middleware } from "openapi-fetch";
3
import { ApiClientError } from "./apiClientError.js";
4
import type { components, paths, operations } from "./openapi.js";
5
import type { CommonProperties, TelemetryEvent } from "../../telemetry/types.js";
6
import { packageInfo } from "../packageInfo.js";
7
import type { LoggerBase } from "../logging/index.js";
8
import { createFetch } from "@mongodb-js/devtools-proxy-support";
9
import { Request as NodeFetchRequest } from "node-fetch";
10
import type { Credentials, AuthProvider } from "./auth/authProvider.js";
11
import { AuthProviderFactory } from "./auth/authProvider.js";
12

13
const ATLAS_API_VERSION = "2025-03-12";
66✔
14
const LEGACY_ATLAS_API_VERSION = "2023-01-01";
66✔
15
const DEFAULT_SEND_TIMEOUT_MS = 5_000;
66✔
16

17
/**
18
 * Detects whether we're running on Node.js as opposed to a browser/web
19
 * environment. We rely on `process.versions.node` rather than `typeof process`
20
 * because bundlers (e.g. Vite) may replace `process` with a literal object
21
 * shim in the browser build, which would still be `"object"` at runtime.
22
 */
23
function isNodeRuntime(): boolean {
24
    return typeof process !== "undefined" && process.versions !== undefined && process.versions.node !== undefined;
787✔
25
}
26

27
export interface ApiClientOptions {
28
    baseUrl: string;
29
    userAgent?: string;
30
    credentials?: Credentials;
31
    requestContext?: RequestContext;
32
}
33

34
export type RequestContext = {
35
    headers?: Record<string, string | string[] | undefined>;
36
};
37

38
export type ApiClientFactoryFn = (options: ApiClientOptions, logger: LoggerBase) => ApiClient;
39

40
export const defaultCreateApiClient: ApiClientFactoryFn = (options, logger) => {
66✔
41
    return new ApiClient(options, logger);
166✔
42
};
43

44
export class ApiClient {
45
    private readonly options: {
46
        baseUrl: string;
47
        userAgent: string;
48
    };
49

50
    private customFetch: typeof fetch;
51

52
    private client: Client<paths>;
53

54
    public isAuthConfigured(): boolean {
55
        return !!this.authProvider;
15✔
56
    }
57

58
    constructor(
59
        options: ApiClientOptions,
60
        public readonly logger: LoggerBase,
268✔
61
        public readonly authProvider?: AuthProvider
268✔
62
    ) {
63
        // In Node we use `createFetch` from devtools-proxy-support to pick up
64
        // environment-variable proxy configuration and system CA trust, and we
65
        // use node-fetch's Request since its interface is a superset of the
66
        // web Request. In the browser those Node-only concerns don't apply and
67
        // the implementations aren't available, so we fall back to the native
68
        // `fetch`/`Request` globals.
69
        if (isNodeRuntime()) {
268!
70
            // createFetch assumes that the first parameter of fetch is always a string
71
            // with the URL. However, fetch can also receive a Request object. While
72
            // the typechecking complains, createFetch does passthrough the parameters
73
            // so it works fine. That said, node-fetch has incompatibilities with the web version
74
            // of fetch and can lead to genuine issues so we would like to move away of node-fetch dependency.
75
            this.customFetch = createFetch({
268✔
76
                useEnvironmentVariableProxies: true,
77
            }) as unknown as typeof fetch;
78
        } else {
79
            this.customFetch = globalThis.fetch.bind(globalThis);
×
80
        }
81
        this.options = {
268✔
82
            ...options,
83
            userAgent:
84
                options.userAgent ??
519✔
85
                `AtlasMCP/${packageInfo.version} (${isNodeRuntime() ? `${process.platform}; ${process.arch}` : "browser"})`,
251!
86
        };
87

88
        this.authProvider =
268✔
89
            authProvider ??
536✔
90
            AuthProviderFactory.create(
91
                {
92
                    apiBaseUrl: this.options.baseUrl,
93
                    userAgent: this.options.userAgent,
94
                    credentials: options.credentials ?? {},
352✔
95
                },
96
                logger
97
            );
98

99
        this.client = createClient<paths>({
268✔
100
            baseUrl: this.options.baseUrl,
101
            headers: {
102
                "User-Agent": this.options.userAgent,
103
                Accept: `application/vnd.atlas.${ATLAS_API_VERSION}+json`,
104
            },
105
            fetch: this.customFetch,
106
            // NodeFetchRequest has more overloadings than the native Request
107
            // so it complains here. However, the interfaces are actually compatible
108
            // so it's not a real problem, just a type checking problem.
109
            Request: (isNodeRuntime() ? NodeFetchRequest : globalThis.Request) as unknown as ClientOptions["Request"],
268!
110
        });
111

112
        if (this.authProvider) {
268✔
113
            this.client.use(this.createAuthMiddleware());
37✔
114
        }
115
    }
116

117
    private createAuthMiddleware(): Middleware {
118
        return {
37✔
119
            onRequest: async ({ request, schemaPath }): Promise<Request | undefined> => {
120
                if (schemaPath.startsWith("/api/private/unauth") || schemaPath.startsWith("/api/oauth")) {
228!
121
                    return undefined;
×
122
                }
123

124
                try {
228✔
125
                    const authHeaders = (await this.authProvider?.getAuthHeaders()) ?? {};
228✔
126
                    for (const [key, value] of Object.entries(authHeaders)) {
228✔
127
                        request.headers.set(key, value);
227✔
128
                    }
129
                    return request;
228✔
130
                } catch {
131
                    // ignore not available tokens, API will return 401
132
                    return undefined;
×
133
                }
134
            },
135
        };
136
    }
137

138
    public async validateAuthConfig(): Promise<void> {
139
        await this.authProvider?.validate();
32✔
140
    }
141

142
    public async close(): Promise<void> {
143
        await this.authProvider?.revoke();
131✔
144
    }
145

146
    public async getIpInfo(): Promise<{
147
        currentIpv4Address: string;
148
    }> {
149
        const authHeaders = (await this.authProvider?.getAuthHeaders()) ?? {};
38✔
150

151
        const endpoint = "api/private/ipinfo";
38✔
152
        const url = new URL(endpoint, this.options.baseUrl);
38✔
153
        const response = await fetch(url, {
38✔
154
            method: "GET",
155
            headers: {
156
                ...authHeaders,
157
                Accept: "application/json",
158
                "User-Agent": this.options.userAgent,
159
            },
160
        });
161

162
        if (!response.ok) {
38✔
163
            throw await ApiClientError.fromResponse(response);
2✔
164
        }
165

166
        return (await response.json()) as Promise<{
36✔
167
            currentIpv4Address: string;
168
        }>;
169
    }
170

171
    public async sendEvents(
172
        events: TelemetryEvent<CommonProperties>[],
173
        { signal = AbortSignal.timeout(DEFAULT_SEND_TIMEOUT_MS) }: { signal?: AbortSignal } = {}
20✔
174
    ): Promise<void> {
175
        if (!this.authProvider) {
10✔
176
            await this.sendUnauthEvents(events, signal);
1✔
177
            return;
1✔
178
        }
179

180
        try {
9✔
181
            await this.sendAuthEvents(events, signal);
9✔
182
        } catch (error) {
183
            if (error instanceof ApiClientError) {
6✔
184
                if (error.response.status !== 401) {
2!
185
                    throw error;
×
186
                }
187
            }
188

189
            // send unauth events if any of the following are true:
190
            // 1: the token is not valid (not ApiClientError)
191
            // 2: if the api responded with 401 (ApiClientError with status 401)
192
            await this.sendUnauthEvents(events, signal);
6✔
193
        }
194
    }
195

196
    private async sendAuthEvents(events: TelemetryEvent<CommonProperties>[], signal?: AbortSignal): Promise<void> {
197
        const authHeaders = await this.authProvider?.getAuthHeaders();
9✔
198
        if (!authHeaders) {
6✔
199
            throw new Error("No access token available");
1✔
200
        }
201
        const authUrl = new URL("api/private/v1.0/telemetry/events", this.options.baseUrl);
5✔
202
        const response = await fetch(authUrl, {
5✔
203
            method: "POST",
204
            headers: {
205
                ...authHeaders,
206
                Accept: "application/json",
207
                "Content-Type": "application/json",
208
                "User-Agent": this.options.userAgent,
209
            },
210
            body: JSON.stringify(events),
211
            signal,
212
        });
213

214
        if (!response.ok) {
5✔
215
            throw await ApiClientError.fromResponse(response);
2✔
216
        }
217
    }
218

219
    private async sendUnauthEvents(events: TelemetryEvent<CommonProperties>[], signal?: AbortSignal): Promise<void> {
220
        const headers: Record<string, string> = {
7✔
221
            Accept: "application/json",
222
            "Content-Type": "application/json",
223
            "User-Agent": this.options.userAgent,
224
        };
225

226
        const unauthUrl = new URL("api/private/unauth/telemetry/events", this.options.baseUrl);
7✔
227
        const response = await fetch(unauthUrl, {
7✔
228
            method: "POST",
229
            headers,
230
            body: JSON.stringify(events),
231
            signal,
232
        });
233

234
        if (!response.ok) {
7✔
235
            throw await ApiClientError.fromResponse(response);
1✔
236
        }
237
    }
238

239
    // DO NOT EDIT. This is auto-generated code.
240
    /* eslint-disable @typescript-eslint/no-unsafe-assignment */
241
    async listClusterDetails(
242
        options?: FetchOptions<operations["listClusterDetails"]>
243
    ): Promise<components["schemas"]["PaginatedOrgGroupView"]> {
244
        const { data, error, response } = await this.client.GET("/api/atlas/v2/clusters", options);
×
245
        if (error) {
×
246
            throw ApiClientError.fromError(response, error);
×
247
        }
248
        return data;
×
249
    }
250

251
    async listGroups(
252
        options?: FetchOptions<operations["listGroups"]>
253
    ): Promise<components["schemas"]["PaginatedAtlasGroupView"]> {
254
        const { data, error, response } = await this.client.GET("/api/atlas/v2/groups", options);
4✔
255
        if (error) {
4✔
256
            throw ApiClientError.fromError(response, error);
1✔
257
        }
258
        return data;
3✔
259
    }
260

261
    async createGroup(options: FetchOptions<operations["createGroup"]>): Promise<components["schemas"]["Group"]> {
262
        const { data, error, response } = await this.client.POST("/api/atlas/v2/groups", options);
13✔
263
        if (error) {
13!
264
            throw ApiClientError.fromError(response, error);
×
265
        }
266
        return data;
13✔
267
    }
268

269
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
270
    async deleteGroup(options: FetchOptions<operations["deleteGroup"]>) {
271
        const { error, response } = await this.client.DELETE("/api/atlas/v2/groups/{groupId}", options);
13✔
272
        if (error) {
13✔
273
            throw ApiClientError.fromError(response, error);
8✔
274
        }
275
    }
276

277
    async getGroup(options: FetchOptions<operations["getGroup"]>): Promise<components["schemas"]["Group"]> {
278
        const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}", options);
1✔
279
        if (error) {
1!
280
            throw ApiClientError.fromError(response, error);
×
281
        }
282
        return data;
1✔
283
    }
284

285
    async listAccessListEntries(
286
        options: FetchOptions<operations["listGroupAccessListEntries"]>
287
    ): Promise<components["schemas"]["PaginatedNetworkAccessView"]> {
288
        const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/accessList", options);
4✔
289
        if (error) {
4!
290
            throw ApiClientError.fromError(response, error);
×
291
        }
292
        return data;
4✔
293
    }
294

295
    async createAccessListEntry(
296
        options: FetchOptions<operations["createGroupAccessListEntry"]>
297
    ): Promise<components["schemas"]["PaginatedNetworkAccessView"]> {
298
        const { data, error, response } = await this.client.POST("/api/atlas/v2/groups/{groupId}/accessList", options);
24✔
299
        if (error) {
24✔
300
            throw ApiClientError.fromError(response, error);
1✔
301
        }
302
        return data;
23✔
303
    }
304

305
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
306
    async deleteAccessListEntry(options: FetchOptions<operations["deleteGroupAccessListEntry"]>) {
307
        const { error, response } = await this.client.DELETE(
5✔
308
            "/api/atlas/v2/groups/{groupId}/accessList/{entryValue}",
309
            options
310
        );
311
        if (error) {
5!
312
            throw ApiClientError.fromError(response, error);
×
313
        }
314
    }
315

316
    async listAlerts(
317
        options: FetchOptions<operations["listGroupAlerts"]>
318
    ): Promise<components["schemas"]["PaginatedAlertView"]> {
319
        const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/alerts", options);
3✔
320
        if (error) {
3!
321
            throw ApiClientError.fromError(response, error);
×
322
        }
323
        return data;
3✔
324
    }
325

326
    async listClusters(
327
        options: FetchOptions<operations["listGroupClusters"]>
328
    ): Promise<components["schemas"]["PaginatedClusterDescription20240805"]> {
329
        const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/clusters", options);
1✔
330
        if (error) {
1!
331
            throw ApiClientError.fromError(response, error);
×
332
        }
333
        return data;
1✔
334
    }
335

336
    async createCluster(
337
        options: FetchOptions<operations["createGroupCluster"]>
338
    ): Promise<components["schemas"]["ClusterDescription20240805"]> {
339
        const { data, error, response } = await this.client.POST("/api/atlas/v2/groups/{groupId}/clusters", options);
8✔
340
        if (error) {
8!
341
            throw ApiClientError.fromError(response, error);
×
342
        }
343
        return data;
8✔
344
    }
345

346
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
347
    async deleteCluster(options: FetchOptions<operations["deleteGroupCluster"]>) {
348
        const { error, response } = await this.client.DELETE(
8✔
349
            "/api/atlas/v2/groups/{groupId}/clusters/{clusterName}",
350
            options
351
        );
352
        if (error) {
8✔
353
            throw ApiClientError.fromError(response, error);
1✔
354
        }
355
    }
356

357
    async getCluster(
358
        options: FetchOptions<operations["getGroupCluster"]>
359
    ): Promise<components["schemas"]["ClusterDescription20240805"]> {
360
        const { data, error, response } = await this.client.GET(
21✔
361
            "/api/atlas/v2/groups/{groupId}/clusters/{clusterName}",
362
            options
363
        );
364
        if (error) {
21!
365
            throw ApiClientError.fromError(response, error);
×
366
        }
367
        return data;
21✔
368
    }
369

370
    async listDropIndexSuggestions(
371
        options: FetchOptions<operations["listGroupClusterPerformanceAdvisorDropIndexSuggestions"]>
372
    ): Promise<components["schemas"]["DropIndexSuggestionsResponse"]> {
373
        const { data, error, response } = await this.client.GET(
×
374
            "/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/performanceAdvisor/dropIndexSuggestions",
375
            options
376
        );
377
        if (error) {
×
378
            throw ApiClientError.fromError(response, error);
×
379
        }
380
        return data;
×
381
    }
382

383
    async listSchemaAdvice(
384
        options: FetchOptions<operations["listGroupClusterPerformanceAdvisorSchemaAdvice"]>
385
    ): Promise<components["schemas"]["SchemaAdvisorResponse"]> {
386
        const { data, error, response } = await this.client.GET(
×
387
            "/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/performanceAdvisor/schemaAdvice",
388
            options
389
        );
390
        if (error) {
×
391
            throw ApiClientError.fromError(response, error);
×
392
        }
393
        return data;
×
394
    }
395

396
    async listClusterSuggestedIndexes(
397
        options: FetchOptions<operations["listGroupClusterPerformanceAdvisorSuggestedIndexes"]>
398
    ): Promise<components["schemas"]["PerformanceAdvisorResponse"]> {
399
        const { data, error, response } = await this.client.GET(
×
400
            "/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/performanceAdvisor/suggestedIndexes",
401
            options
402
        );
403
        if (error) {
×
404
            throw ApiClientError.fromError(response, error);
×
405
        }
406
        return data;
×
407
    }
408

409
    async listDatabaseUsers(
410
        options: FetchOptions<operations["listGroupDatabaseUsers"]>
411
    ): Promise<components["schemas"]["PaginatedApiAtlasDatabaseUserView"]> {
412
        const { data, error, response } = await this.client.GET(
1✔
413
            "/api/atlas/v2/groups/{groupId}/databaseUsers",
414
            options
415
        );
416
        if (error) {
1!
417
            throw ApiClientError.fromError(response, error);
×
418
        }
419
        return data;
1✔
420
    }
421

422
    async createDatabaseUser(
423
        options: FetchOptions<operations["createGroupDatabaseUser"]>
424
    ): Promise<components["schemas"]["CloudDatabaseUser"]> {
425
        const { data, error, response } = await this.client.POST(
7✔
426
            "/api/atlas/v2/groups/{groupId}/databaseUsers",
427
            options
428
        );
429
        if (error) {
7!
430
            throw ApiClientError.fromError(response, error);
×
431
        }
432
        return data;
7✔
433
    }
434

435
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
436
    async deleteDatabaseUser(options: FetchOptions<operations["deleteGroupDatabaseUser"]>) {
437
        const { error, response } = await this.client.DELETE(
10✔
438
            "/api/atlas/v2/groups/{groupId}/databaseUsers/{databaseName}/{username}",
439
            options
440
        );
441
        if (error) {
10✔
442
            throw ApiClientError.fromError(response, error);
3✔
443
        }
444
    }
445

446
    async listFlexClusters(
447
        options: FetchOptions<operations["listGroupFlexClusters"]>
448
    ): Promise<components["schemas"]["PaginatedFlexClusters20241113"]> {
449
        const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/flexClusters", options);
×
450
        if (error) {
×
451
            throw ApiClientError.fromError(response, error);
×
452
        }
453
        return data;
×
454
    }
455

456
    async createFlexCluster(
457
        options: FetchOptions<operations["createGroupFlexCluster"]>
458
    ): Promise<components["schemas"]["FlexClusterDescription20241113"]> {
459
        const { data, error, response } = await this.client.POST(
×
460
            "/api/atlas/v2/groups/{groupId}/flexClusters",
461
            options
462
        );
463
        if (error) {
×
464
            throw ApiClientError.fromError(response, error);
×
465
        }
466
        return data;
×
467
    }
468

469
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
470
    async deleteFlexCluster(options: FetchOptions<operations["deleteGroupFlexCluster"]>) {
471
        const { error, response } = await this.client.DELETE(
×
472
            "/api/atlas/v2/groups/{groupId}/flexClusters/{name}",
473
            options
474
        );
475
        if (error) {
×
476
            throw ApiClientError.fromError(response, error);
×
477
        }
478
    }
479

480
    async getFlexCluster(
481
        options: FetchOptions<operations["getGroupFlexCluster"]>
482
    ): Promise<components["schemas"]["FlexClusterDescription20241113"]> {
483
        const { data, error, response } = await this.client.GET(
×
484
            "/api/atlas/v2/groups/{groupId}/flexClusters/{name}",
485
            options
486
        );
487
        if (error) {
×
488
            throw ApiClientError.fromError(response, error);
×
489
        }
490
        return data;
×
491
    }
492

493
    async listSlowQueryLogs(
494
        options: FetchOptions<operations["listGroupProcessPerformanceAdvisorSlowQueryLogs"]>
495
    ): Promise<components["schemas"]["PerformanceAdvisorSlowQueryList"]> {
496
        const { data, error, response } = await this.client.GET(
×
497
            "/api/atlas/v2/groups/{groupId}/processes/{processId}/performanceAdvisor/slowQueryLogs",
498
            options
499
        );
500
        if (error) {
×
501
            throw ApiClientError.fromError(response, error);
×
502
        }
503
        return data;
×
504
    }
505

506
    async listStreamWorkspaces(
507
        options: FetchOptions<operations["listGroupStreamWorkspaces"]>
508
    ): Promise<components["schemas"]["PaginatedApiStreamsTenantView"]> {
509
        const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/streams", options);
3✔
510
        if (error) {
3!
511
            throw ApiClientError.fromError(response, error);
×
512
        }
513
        return data;
3✔
514
    }
515

516
    async createStreamWorkspace(
517
        options: FetchOptions<operations["createGroupStreamWorkspace"]>
518
    ): Promise<components["schemas"]["StreamsTenant"]> {
519
        const { data, error, response } = await this.client.POST("/api/atlas/v2/groups/{groupId}/streams", options);
6✔
520
        if (error) {
6!
521
            throw ApiClientError.fromError(response, error);
×
522
        }
523
        return data;
6✔
524
    }
525

526
    async getAccountDetails(
527
        options: FetchOptions<operations["getGroupStreamAccountDetails"]>
528
    ): Promise<components["schemas"]["AccountDetails"]> {
529
        const { data, error, response } = await this.client.GET(
×
530
            "/api/atlas/v2/groups/{groupId}/streams/accountDetails",
531
            options
532
        );
533
        if (error) {
×
534
            throw ApiClientError.fromError(response, error);
×
535
        }
536
        return data;
×
537
    }
538

539
    async listPrivateLinkConnections(
540
        options: FetchOptions<operations["listGroupStreamPrivateLinkConnections"]>
541
    ): Promise<components["schemas"]["PaginatedApiStreamsPrivateLinkView"]> {
542
        const { data, error, response } = await this.client.GET(
1✔
543
            "/api/atlas/v2/groups/{groupId}/streams/privateLinkConnections",
544
            options
545
        );
546
        if (error) {
1!
547
            throw ApiClientError.fromError(response, error);
×
548
        }
549
        return data;
1✔
550
    }
551

552
    async createPrivateLinkConnection(
553
        options: FetchOptions<operations["createGroupStreamPrivateLinkConnection"]>
554
    ): Promise<components["schemas"]["StreamsPrivateLinkConnection"]> {
555
        const { data, error, response } = await this.client.POST(
×
556
            "/api/atlas/v2/groups/{groupId}/streams/privateLinkConnections",
557
            options
558
        );
559
        if (error) {
×
560
            throw ApiClientError.fromError(response, error);
×
561
        }
562
        return data;
×
563
    }
564

565
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
566
    async deletePrivateLinkConnection(options: FetchOptions<operations["deleteGroupStreamPrivateLinkConnection"]>) {
567
        const { error, response } = await this.client.DELETE(
×
568
            "/api/atlas/v2/groups/{groupId}/streams/privateLinkConnections/{connectionId}",
569
            options
570
        );
571
        if (error) {
×
572
            throw ApiClientError.fromError(response, error);
×
573
        }
574
    }
575

576
    async getPrivateLinkConnection(
577
        options: FetchOptions<operations["getGroupStreamPrivateLinkConnection"]>
578
    ): Promise<components["schemas"]["StreamsPrivateLinkConnection"]> {
579
        const { data, error, response } = await this.client.GET(
×
580
            "/api/atlas/v2/groups/{groupId}/streams/privateLinkConnections/{connectionId}",
581
            options
582
        );
583
        if (error) {
×
584
            throw ApiClientError.fromError(response, error);
×
585
        }
586
        return data;
×
587
    }
588

589
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
590
    async deleteVpcPeeringConnection(options: FetchOptions<operations["deleteGroupStreamVpcPeeringConnection"]>) {
591
        const { error, response } = await this.client.DELETE(
×
592
            "/api/atlas/v2/groups/{groupId}/streams/vpcPeeringConnections/{id}",
593
            options
594
        );
595
        if (error) {
×
596
            throw ApiClientError.fromError(response, error);
×
597
        }
598
    }
599

600
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
601
    async acceptVpcPeeringConnection(options: FetchOptions<operations["acceptGroupStreamVpcPeeringConnection"]>) {
602
        const { error, response } = await this.client.POST(
×
603
            "/api/atlas/v2/groups/{groupId}/streams/vpcPeeringConnections/{id}:accept",
604
            options
605
        );
606
        if (error) {
×
607
            throw ApiClientError.fromError(response, error);
×
608
        }
609
    }
610

611
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
612
    async rejectVpcPeeringConnection(options: FetchOptions<operations["rejectGroupStreamVpcPeeringConnection"]>) {
613
        const { error, response } = await this.client.POST(
×
614
            "/api/atlas/v2/groups/{groupId}/streams/vpcPeeringConnections/{id}:reject",
615
            options
616
        );
617
        if (error) {
×
618
            throw ApiClientError.fromError(response, error);
×
619
        }
620
    }
621

622
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
623
    async deleteStreamWorkspace(options: FetchOptions<operations["deleteGroupStreamWorkspace"]>) {
624
        const { error, response } = await this.client.DELETE(
7✔
625
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}",
626
            options
627
        );
628
        if (error) {
7✔
629
            throw ApiClientError.fromError(response, error);
2✔
630
        }
631
    }
632

633
    async getStreamWorkspace(
634
        options: FetchOptions<operations["getGroupStreamWorkspace"]>
635
    ): Promise<components["schemas"]["StreamsTenant"]> {
636
        const { data, error, response } = await this.client.GET(
11✔
637
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}",
638
            options
639
        );
640
        if (error) {
11✔
641
            throw ApiClientError.fromError(response, error);
4✔
642
        }
643
        return data;
7✔
644
    }
645

646
    async updateStreamWorkspace(
647
        options: FetchOptions<operations["updateGroupStreamWorkspace"]>
648
    ): Promise<components["schemas"]["StreamsTenant"]> {
649
        const { data, error, response } = await this.client.PATCH(
2✔
650
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}",
651
            options
652
        );
653
        if (error) {
2!
654
            throw ApiClientError.fromError(response, error);
×
655
        }
656
        return data;
2✔
657
    }
658

659
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
660
    async downloadAuditLogs(options: FetchOptions<operations["downloadGroupStreamAuditLogs"]>) {
661
        const { data, error, response } = await this.client.GET(
×
662
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/auditLogs",
663
            { ...options, headers: { Accept: "application/vnd.atlas.2023-02-01+gzip", ...options?.headers } }
664
        );
665
        if (error) {
×
666
            throw ApiClientError.fromError(response, error);
×
667
        }
668
        return data;
×
669
    }
670

671
    async listStreamConnections(
672
        options: FetchOptions<operations["listGroupStreamConnections"]>
673
    ): Promise<components["schemas"]["PaginatedApiStreamsConnectionView"]> {
674
        const { data, error, response } = await this.client.GET(
6✔
675
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/connections",
676
            options
677
        );
678
        if (error) {
6!
679
            throw ApiClientError.fromError(response, error);
×
680
        }
681
        return data;
6✔
682
    }
683

684
    async createStreamConnection(
685
        options: FetchOptions<operations["createGroupStreamConnection"]>
686
    ): Promise<components["schemas"]["StreamsConnection"]> {
687
        const { data, error, response } = await this.client.POST(
16✔
688
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/connections",
689
            options
690
        );
691
        if (error) {
16!
692
            throw ApiClientError.fromError(response, error);
×
693
        }
694
        return data;
16✔
695
    }
696

697
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
698
    async deleteStreamConnection(options: FetchOptions<operations["deleteGroupStreamConnection"]>) {
699
        const { error, response } = await this.client.DELETE(
6✔
700
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/connections/{connectionName}",
701
            options
702
        );
703
        if (error) {
6!
704
            throw ApiClientError.fromError(response, error);
×
705
        }
706
    }
707

708
    async getStreamConnection(
709
        options: FetchOptions<operations["getGroupStreamConnection"]>
710
    ): Promise<components["schemas"]["StreamsConnection"]> {
711
        const { data, error, response } = await this.client.GET(
5✔
712
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/connections/{connectionName}",
713
            options
714
        );
715
        if (error) {
5✔
716
            throw ApiClientError.fromError(response, error);
1✔
717
        }
718
        return data;
4✔
719
    }
720

721
    async updateStreamConnection(
722
        options: FetchOptions<operations["updateGroupStreamConnection"]>
723
    ): Promise<components["schemas"]["StreamsConnection"]> {
724
        const { data, error, response } = await this.client.PATCH(
1✔
725
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/connections/{connectionName}",
726
            options
727
        );
728
        if (error) {
1!
729
            throw ApiClientError.fromError(response, error);
×
730
        }
731
        return data;
1✔
732
    }
733

734
    async createStreamProcessor(
735
        options: FetchOptions<operations["createGroupStreamProcessor"]>
736
    ): Promise<components["schemas"]["StreamsProcessor"]> {
737
        const { data, error, response } = await this.client.POST(
2✔
738
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor",
739
            options
740
        );
741
        if (error) {
2!
742
            throw ApiClientError.fromError(response, error);
×
743
        }
744
        return data;
2✔
745
    }
746

747
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
748
    async deleteStreamProcessor(options: FetchOptions<operations["deleteGroupStreamProcessor"]>) {
749
        const { error, response } = await this.client.DELETE(
1✔
750
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor/{processorName}",
751
            options
752
        );
753
        if (error) {
1!
754
            throw ApiClientError.fromError(response, error);
×
755
        }
756
    }
757

758
    async getStreamProcessor(
759
        options: FetchOptions<operations["getGroupStreamProcessor"]>
760
    ): Promise<components["schemas"]["StreamsProcessorWithStats"]> {
761
        const { data, error, response } = await this.client.GET(
11✔
762
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor/{processorName}",
763
            options
764
        );
765
        if (error) {
11!
766
            throw ApiClientError.fromError(response, error);
×
767
        }
768
        return data;
11✔
769
    }
770

771
    async updateStreamProcessor(
772
        options: FetchOptions<operations["updateGroupStreamProcessor"]>
773
    ): Promise<components["schemas"]["StreamsProcessorWithStats"]> {
774
        const { data, error, response } = await this.client.PATCH(
2✔
775
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor/{processorName}",
776
            options
777
        );
778
        if (error) {
2!
779
            throw ApiClientError.fromError(response, error);
×
780
        }
781
        return data;
2✔
782
    }
783

784
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
785
    async startStreamProcessor(options: FetchOptions<operations["startGroupStreamProcessor"]>) {
786
        const { error, response } = await this.client.POST(
2✔
787
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor/{processorName}:start",
788
            options
789
        );
790
        if (error) {
2!
791
            throw ApiClientError.fromError(response, error);
×
792
        }
793
    }
794

795
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
796
    async startStreamProcessorWith(options: FetchOptions<operations["startGroupStreamProcessorWith"]>) {
797
        const { error, response } = await this.client.POST(
×
798
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor/{processorName}:startWith",
799
            options
800
        );
801
        if (error) {
×
802
            throw ApiClientError.fromError(response, error);
×
803
        }
804
    }
805

806
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
807
    async stopStreamProcessor(options: FetchOptions<operations["stopGroupStreamProcessor"]>) {
808
        const { error, response } = await this.client.POST(
2✔
809
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/processor/{processorName}:stop",
810
            options
811
        );
812
        if (error) {
2!
813
            throw ApiClientError.fromError(response, error);
×
814
        }
815
    }
816

817
    async getStreamProcessors(
818
        options: FetchOptions<operations["getGroupStreamProcessors"]>
819
    ): Promise<components["schemas"]["PaginatedApiStreamsStreamProcessorWithStatsView"]> {
820
        const { data, error, response } = await this.client.GET(
4✔
821
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}/processors",
822
            options
823
        );
824
        if (error) {
4!
825
            throw ApiClientError.fromError(response, error);
×
826
        }
827
        return data;
4✔
828
    }
829

830
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
831
    async downloadOperationalLogs(options: FetchOptions<operations["downloadGroupStreamOperationalLogs"]>) {
832
        const { data, error, response } = await this.client.GET(
×
833
            "/api/atlas/v2/groups/{groupId}/streams/{tenantName}:downloadOperationalLogs",
834
            { ...options, headers: { Accept: "application/vnd.atlas.2025-03-12+gzip", ...options?.headers } }
835
        );
836
        if (error) {
×
837
            throw ApiClientError.fromError(response, error);
×
838
        }
839
        return data;
×
840
    }
841

842
    async withStreamSampleConnections(
843
        options: FetchOptions<operations["withGroupStreamSampleConnections"]>
844
    ): Promise<components["schemas"]["StreamsTenant"]> {
845
        const { data, error, response } = await this.client.POST(
×
846
            "/api/atlas/v2/groups/{groupId}/streams:withSampleConnections",
847
            options
848
        );
849
        if (error) {
×
850
            throw ApiClientError.fromError(response, error);
×
851
        }
852
        return data;
×
853
    }
854

855
    async listOrgs(
856
        options?: FetchOptions<operations["listOrgs"]>
857
    ): Promise<components["schemas"]["PaginatedOrganizationView"]> {
858
        const { data, error, response } = await this.client.GET("/api/atlas/v2/orgs", options);
18✔
859
        if (error) {
16!
860
            throw ApiClientError.fromError(response, error);
×
861
        }
862
        return data;
16✔
863
    }
864

865
    async getOrgGroups(
866
        options: FetchOptions<operations["getOrgGroups"]>
867
    ): Promise<components["schemas"]["PaginatedAtlasGroupView"]> {
868
        const { data, error, response } = await this.client.GET("/api/atlas/v2/orgs/{orgId}/groups", options);
1✔
869
        if (error) {
1!
870
            throw ApiClientError.fromError(response, error);
×
871
        }
872
        return data;
1✔
873
    }
874
    /* eslint-enable @typescript-eslint/no-unsafe-assignment */
875
    // DO NOT EDIT. This is auto-generated code.
876

877
    async upgradeSharedTierCluster(options: {
878
        groupId: string;
879
        body: {
880
            name: string;
881
            providerSettings: {
882
                providerName?: string;
883
                instanceSizeName: "FLEX" | "M10";
884
                backingProviderName?: string;
885
                regionName?: string;
886
            };
887
        };
888
    }): Promise<{ id?: string }> {
889
        const authHeaders = (await this.authProvider?.getAuthHeaders()) ?? {};
2!
890
        const url = new URL(`api/atlas/v2/groups/${options.groupId}/clusters/tenantUpgrade`, this.options.baseUrl);
2✔
891
        const response = await this.customFetch(url.toString(), {
2✔
892
            method: "POST",
893
            headers: {
894
                ...authHeaders,
895
                "Content-Type": `application/vnd.atlas.${LEGACY_ATLAS_API_VERSION}+json`,
896
                Accept: `application/vnd.atlas.${LEGACY_ATLAS_API_VERSION}+json`,
897
                "User-Agent": this.options.userAgent,
898
            },
899
            body: JSON.stringify(options.body),
900
        });
901
        if (!response.ok) {
2!
NEW
902
            throw await ApiClientError.fromResponse(response);
×
903
        }
904
        return (await response.json()) as { id?: string };
2✔
905
    }
906

907
    async upgradeFlexToDedicated(options: {
908
        groupId: string;
909
        body: {
910
            name: string;
911
            clusterType: "REPLICASET";
912
            replicationSpecs: Array<{
913
                regionConfigs: Array<{
914
                    providerName?: string;
915
                    regionName?: string;
916
                    priority: number;
917
                    electableSpecs: { instanceSize: string; nodeCount: number };
918
                }>;
919
            }>;
920
            autoScaling: {
921
                compute: {
922
                    enabled: boolean;
923
                    scaleDownEnabled: boolean;
924
                    minInstanceSize: string;
925
                    maxInstanceSize: string;
926
                };
927
                diskGBEnabled: boolean;
928
            };
929
        };
930
    }): Promise<{ id?: string }> {
NEW
931
        const authHeaders = (await this.authProvider?.getAuthHeaders()) ?? {};
×
NEW
932
        const url = new URL(`api/atlas/v2/groups/${options.groupId}/flexClusters:tenantUpgrade`, this.options.baseUrl);
×
NEW
933
        const response = await this.customFetch(url.toString(), {
×
934
            method: "POST",
935
            headers: {
936
                ...authHeaders,
937
                "Content-Type": `application/vnd.atlas.${ATLAS_API_VERSION}+json`,
938
                Accept: `application/vnd.atlas.${ATLAS_API_VERSION}+json`,
939
                "User-Agent": this.options.userAgent,
940
            },
941
            body: JSON.stringify(options.body),
942
        });
NEW
943
        if (!response.ok) {
×
NEW
944
            throw await ApiClientError.fromResponse(response);
×
945
        }
NEW
946
        return (await response.json()) as { id?: string };
×
947
    }
948
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc