Skip to content

Commit 0771380

Browse files
authored
fix: operation ids in the openapi spec (#720)
1 parent 38518ab commit 0771380

23 files changed

+259
-168
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@
5252
"fix": "npm run fix:lint && npm run reformat",
5353
"fix:lint": "eslint . --fix",
5454
"reformat": "prettier --write .",
55-
"generate": "./scripts/generate.sh && npm run generate:arguments",
55+
"generate": "npm run generate:api && npm run generate:arguments",
56+
"generate:api": "./scripts/generate.sh",
5657
"generate:arguments": "tsx scripts/generateArguments.ts",
5758
"test": "vitest --project eslint-rules --project unit-and-integration --coverage",
5859
"pretest:accuracy": "npm run build",

scripts/apply.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ async function main(): Promise<void> {
3636
path: string;
3737
method: string;
3838
operationId: string;
39+
methodName: string;
3940
requiredParams: boolean;
4041
tag: string;
4142
hasResponseBody: boolean;
@@ -45,7 +46,9 @@ async function main(): Promise<void> {
4546
for (const path in openapi.paths) {
4647
for (const method in openapi.paths[path]) {
4748
// @ts-expect-error This is a workaround for the OpenAPI types
48-
const operation = openapi.paths[path][method] as OpenAPIV3_1.OperationObject;
49+
const operation = openapi.paths[path][method] as OpenAPIV3_1.OperationObject & {
50+
"x-xgen-operation-id-override": string;
51+
};
4952

5053
if (!operation.operationId || !operation.tags?.length) {
5154
continue;
@@ -81,6 +84,7 @@ async function main(): Promise<void> {
8184
operations.push({
8285
path,
8386
method: method.toUpperCase(),
87+
methodName: operation["x-xgen-operation-id-override"] || operation.operationId || "",
8488
operationId: operation.operationId || "",
8589
requiredParams,
8690
hasResponseBody,
@@ -91,9 +95,9 @@ async function main(): Promise<void> {
9195

9296
const operationOutput = operations
9397
.map((operation) => {
94-
const { operationId, method, path, requiredParams, hasResponseBody } = operation;
98+
const { methodName, operationId, method, path, requiredParams, hasResponseBody } = operation;
9599
return `// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
96-
async ${operationId}(options${requiredParams ? "" : "?"}: FetchOptions<operations["${operationId}"]>) {
100+
async ${methodName}(options${requiredParams ? "" : "?"}: FetchOptions<operations["${operationId}"]>) {
97101
const { ${hasResponseBody ? `data, ` : ``}error, response } = await this.client.${method}("${path}", options);
98102
if (error) {
99103
throw ApiClientError.fromError(response, error);

scripts/cleanupAtlasTestLeftovers.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function isOlderThanTwoHours(date: string): boolean {
1212
}
1313

1414
async function findTestOrganization(client: ApiClient): Promise<AtlasOrganization> {
15-
const orgs = await client.listOrganizations();
15+
const orgs = await client.listOrgs();
1616
const testOrg = orgs?.results?.find((org) => org.name === "MongoDB MCP Test");
1717

1818
if (!testOrg) {
@@ -23,7 +23,7 @@ async function findTestOrganization(client: ApiClient): Promise<AtlasOrganizatio
2323
}
2424

2525
async function findAllTestProjects(client: ApiClient, orgId: string): Promise<Group[]> {
26-
const projects = await client.listOrganizationProjects({
26+
const projects = await client.getOrgGroups({
2727
params: {
2828
path: {
2929
orgId,
@@ -101,7 +101,7 @@ async function main(): Promise<void> {
101101

102102
// Try to delete the project
103103
try {
104-
await apiClient.deleteProject({
104+
await apiClient.deleteGroup({
105105
params: {
106106
path: {
107107
groupId: project.id,

scripts/filter.ts

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ async function readStdin(): Promise<string> {
1919

2020
function filterOpenapi(openapi: OpenAPIV3_1.Document): OpenAPIV3_1.Document {
2121
const allowedOperations = [
22-
"listProjects",
23-
"listOrganizations",
24-
"getProject",
25-
"createProject",
26-
"deleteProject",
22+
"listGroups",
23+
"listOrgs",
24+
"getGroup",
25+
"createGroup",
26+
"deleteGroup",
2727
"listClusters",
2828
"listFlexClusters",
2929
"getCluster",
@@ -32,28 +32,35 @@ function filterOpenapi(openapi: OpenAPIV3_1.Document): OpenAPIV3_1.Document {
3232
"createFlexCluster",
3333
"deleteCluster",
3434
"deleteFlexCluster",
35-
"listClustersForAllProjects",
35+
"listClusterDetails",
3636
"createDatabaseUser",
3737
"deleteDatabaseUser",
3838
"listDatabaseUsers",
39-
"listProjectIpAccessLists",
40-
"createProjectIpAccessList",
41-
"deleteProjectIpAccessList",
42-
"listOrganizationProjects",
39+
"listAccessListEntries",
40+
"createAccessListEntry",
41+
"deleteAccessListEntry",
42+
"getOrgGroups",
4343
"listAlerts",
44-
"listDropIndexes",
44+
"listDropIndexSuggestions",
4545
"listClusterSuggestedIndexes",
4646
"listSchemaAdvice",
47-
"listSlowQueries",
47+
"listSlowQueryLogs",
4848
];
4949

5050
const filteredPaths = {};
5151

5252
for (const path in openapi.paths) {
5353
const filteredMethods = {} as OpenAPIV3_1.PathItemObject;
54-
for (const method in openapi.paths[path]) {
55-
// @ts-expect-error This is a workaround for the OpenAPI types
56-
if (allowedOperations.includes((openapi.paths[path][method] as { operationId: string }).operationId)) {
54+
// @ts-expect-error This is a workaround for the OpenAPI types
55+
for (const [method, operation] of Object.entries(openapi.paths[path])) {
56+
const op = operation as OpenAPIV3_1.OperationObject & {
57+
"x-xgen-operation-id-override": string;
58+
};
59+
if (
60+
op.operationId &&
61+
(allowedOperations.includes(op.operationId) ||
62+
allowedOperations.includes(op["x-xgen-operation-id-override"]))
63+
) {
5764
// @ts-expect-error This is a workaround for the OpenAPI types
5865
filteredMethods[method] = openapi.paths[path][method] as OpenAPIV3_1.OperationObject;
5966
}

src/common/atlas/accessListUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export async function makeCurrentIpAccessListEntry(
2727
export async function ensureCurrentIpInAccessList(apiClient: ApiClient, projectId: string): Promise<boolean> {
2828
const entry = await makeCurrentIpAccessListEntry(apiClient, projectId, DEFAULT_ACCESS_LIST_COMMENT);
2929
try {
30-
await apiClient.createProjectIpAccessList({
30+
await apiClient.createAccessListEntry({
3131
params: { path: { groupId: projectId } },
3232
body: [entry],
3333
});

src/common/atlas/apiClient.ts

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ export class ApiClient {
307307

308308
// DO NOT EDIT. This is auto-generated code.
309309
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
310-
async listClustersForAllProjects(options?: FetchOptions<operations["listClustersForAllProjects"]>) {
310+
async listClusterDetails(options?: FetchOptions<operations["listClusterDetails"]>) {
311311
const { data, error, response } = await this.client.GET("/api/atlas/v2/clusters", options);
312312
if (error) {
313313
throw ApiClientError.fromError(response, error);
@@ -316,7 +316,7 @@ export class ApiClient {
316316
}
317317

318318
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
319-
async listProjects(options?: FetchOptions<operations["listProjects"]>) {
319+
async listGroups(options?: FetchOptions<operations["listGroups"]>) {
320320
const { data, error, response } = await this.client.GET("/api/atlas/v2/groups", options);
321321
if (error) {
322322
throw ApiClientError.fromError(response, error);
@@ -325,7 +325,7 @@ export class ApiClient {
325325
}
326326

327327
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
328-
async createProject(options: FetchOptions<operations["createProject"]>) {
328+
async createGroup(options: FetchOptions<operations["createGroup"]>) {
329329
const { data, error, response } = await this.client.POST("/api/atlas/v2/groups", options);
330330
if (error) {
331331
throw ApiClientError.fromError(response, error);
@@ -334,15 +334,15 @@ export class ApiClient {
334334
}
335335

336336
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
337-
async deleteProject(options: FetchOptions<operations["deleteProject"]>) {
337+
async deleteGroup(options: FetchOptions<operations["deleteGroup"]>) {
338338
const { error, response } = await this.client.DELETE("/api/atlas/v2/groups/{groupId}", options);
339339
if (error) {
340340
throw ApiClientError.fromError(response, error);
341341
}
342342
}
343343

344344
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
345-
async getProject(options: FetchOptions<operations["getProject"]>) {
345+
async getGroup(options: FetchOptions<operations["getGroup"]>) {
346346
const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}", options);
347347
if (error) {
348348
throw ApiClientError.fromError(response, error);
@@ -351,7 +351,7 @@ export class ApiClient {
351351
}
352352

353353
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
354-
async listProjectIpAccessLists(options: FetchOptions<operations["listProjectIpAccessLists"]>) {
354+
async listAccessListEntries(options: FetchOptions<operations["listGroupAccessListEntries"]>) {
355355
const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/accessList", options);
356356
if (error) {
357357
throw ApiClientError.fromError(response, error);
@@ -360,7 +360,7 @@ export class ApiClient {
360360
}
361361

362362
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
363-
async createProjectIpAccessList(options: FetchOptions<operations["createProjectIpAccessList"]>) {
363+
async createAccessListEntry(options: FetchOptions<operations["createGroupAccessListEntry"]>) {
364364
const { data, error, response } = await this.client.POST("/api/atlas/v2/groups/{groupId}/accessList", options);
365365
if (error) {
366366
throw ApiClientError.fromError(response, error);
@@ -369,7 +369,7 @@ export class ApiClient {
369369
}
370370

371371
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
372-
async deleteProjectIpAccessList(options: FetchOptions<operations["deleteProjectIpAccessList"]>) {
372+
async deleteAccessListEntry(options: FetchOptions<operations["deleteGroupAccessListEntry"]>) {
373373
const { error, response } = await this.client.DELETE(
374374
"/api/atlas/v2/groups/{groupId}/accessList/{entryValue}",
375375
options
@@ -380,7 +380,7 @@ export class ApiClient {
380380
}
381381

382382
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
383-
async listAlerts(options: FetchOptions<operations["listAlerts"]>) {
383+
async listAlerts(options: FetchOptions<operations["listGroupAlerts"]>) {
384384
const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/alerts", options);
385385
if (error) {
386386
throw ApiClientError.fromError(response, error);
@@ -389,7 +389,7 @@ export class ApiClient {
389389
}
390390

391391
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
392-
async listClusters(options: FetchOptions<operations["listClusters"]>) {
392+
async listClusters(options: FetchOptions<operations["listGroupClusters"]>) {
393393
const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/clusters", options);
394394
if (error) {
395395
throw ApiClientError.fromError(response, error);
@@ -398,7 +398,7 @@ export class ApiClient {
398398
}
399399

400400
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
401-
async createCluster(options: FetchOptions<operations["createCluster"]>) {
401+
async createCluster(options: FetchOptions<operations["createGroupCluster"]>) {
402402
const { data, error, response } = await this.client.POST("/api/atlas/v2/groups/{groupId}/clusters", options);
403403
if (error) {
404404
throw ApiClientError.fromError(response, error);
@@ -407,7 +407,7 @@ export class ApiClient {
407407
}
408408

409409
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
410-
async deleteCluster(options: FetchOptions<operations["deleteCluster"]>) {
410+
async deleteCluster(options: FetchOptions<operations["deleteGroupCluster"]>) {
411411
const { error, response } = await this.client.DELETE(
412412
"/api/atlas/v2/groups/{groupId}/clusters/{clusterName}",
413413
options
@@ -418,7 +418,7 @@ export class ApiClient {
418418
}
419419

420420
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
421-
async getCluster(options: FetchOptions<operations["getCluster"]>) {
421+
async getCluster(options: FetchOptions<operations["getGroupCluster"]>) {
422422
const { data, error, response } = await this.client.GET(
423423
"/api/atlas/v2/groups/{groupId}/clusters/{clusterName}",
424424
options
@@ -430,7 +430,9 @@ export class ApiClient {
430430
}
431431

432432
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
433-
async listDropIndexes(options: FetchOptions<operations["listDropIndexes"]>) {
433+
async listDropIndexSuggestions(
434+
options: FetchOptions<operations["listGroupClusterPerformanceAdvisorDropIndexSuggestions"]>
435+
) {
434436
const { data, error, response } = await this.client.GET(
435437
"/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/performanceAdvisor/dropIndexSuggestions",
436438
options
@@ -442,7 +444,7 @@ export class ApiClient {
442444
}
443445

444446
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
445-
async listSchemaAdvice(options: FetchOptions<operations["listSchemaAdvice"]>) {
447+
async listSchemaAdvice(options: FetchOptions<operations["listGroupClusterPerformanceAdvisorSchemaAdvice"]>) {
446448
const { data, error, response } = await this.client.GET(
447449
"/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/performanceAdvisor/schemaAdvice",
448450
options
@@ -454,7 +456,9 @@ export class ApiClient {
454456
}
455457

456458
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
457-
async listClusterSuggestedIndexes(options: FetchOptions<operations["listClusterSuggestedIndexes"]>) {
459+
async listClusterSuggestedIndexes(
460+
options: FetchOptions<operations["listGroupClusterPerformanceAdvisorSuggestedIndexes"]>
461+
) {
458462
const { data, error, response } = await this.client.GET(
459463
"/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/performanceAdvisor/suggestedIndexes",
460464
options
@@ -466,7 +470,7 @@ export class ApiClient {
466470
}
467471

468472
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
469-
async listDatabaseUsers(options: FetchOptions<operations["listDatabaseUsers"]>) {
473+
async listDatabaseUsers(options: FetchOptions<operations["listGroupDatabaseUsers"]>) {
470474
const { data, error, response } = await this.client.GET(
471475
"/api/atlas/v2/groups/{groupId}/databaseUsers",
472476
options
@@ -478,7 +482,7 @@ export class ApiClient {
478482
}
479483

480484
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
481-
async createDatabaseUser(options: FetchOptions<operations["createDatabaseUser"]>) {
485+
async createDatabaseUser(options: FetchOptions<operations["createGroupDatabaseUser"]>) {
482486
const { data, error, response } = await this.client.POST(
483487
"/api/atlas/v2/groups/{groupId}/databaseUsers",
484488
options
@@ -490,7 +494,7 @@ export class ApiClient {
490494
}
491495

492496
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
493-
async deleteDatabaseUser(options: FetchOptions<operations["deleteDatabaseUser"]>) {
497+
async deleteDatabaseUser(options: FetchOptions<operations["deleteGroupDatabaseUser"]>) {
494498
const { error, response } = await this.client.DELETE(
495499
"/api/atlas/v2/groups/{groupId}/databaseUsers/{databaseName}/{username}",
496500
options
@@ -501,7 +505,7 @@ export class ApiClient {
501505
}
502506

503507
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
504-
async listFlexClusters(options: FetchOptions<operations["listFlexClusters"]>) {
508+
async listFlexClusters(options: FetchOptions<operations["listGroupFlexClusters"]>) {
505509
const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/flexClusters", options);
506510
if (error) {
507511
throw ApiClientError.fromError(response, error);
@@ -510,7 +514,7 @@ export class ApiClient {
510514
}
511515

512516
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
513-
async createFlexCluster(options: FetchOptions<operations["createFlexCluster"]>) {
517+
async createFlexCluster(options: FetchOptions<operations["createGroupFlexCluster"]>) {
514518
const { data, error, response } = await this.client.POST(
515519
"/api/atlas/v2/groups/{groupId}/flexClusters",
516520
options
@@ -522,7 +526,7 @@ export class ApiClient {
522526
}
523527

524528
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
525-
async deleteFlexCluster(options: FetchOptions<operations["deleteFlexCluster"]>) {
529+
async deleteFlexCluster(options: FetchOptions<operations["deleteGroupFlexCluster"]>) {
526530
const { error, response } = await this.client.DELETE(
527531
"/api/atlas/v2/groups/{groupId}/flexClusters/{name}",
528532
options
@@ -533,7 +537,7 @@ export class ApiClient {
533537
}
534538

535539
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
536-
async getFlexCluster(options: FetchOptions<operations["getFlexCluster"]>) {
540+
async getFlexCluster(options: FetchOptions<operations["getGroupFlexCluster"]>) {
537541
const { data, error, response } = await this.client.GET(
538542
"/api/atlas/v2/groups/{groupId}/flexClusters/{name}",
539543
options
@@ -545,7 +549,7 @@ export class ApiClient {
545549
}
546550

547551
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
548-
async listSlowQueries(options: FetchOptions<operations["listSlowQueries"]>) {
552+
async listSlowQueryLogs(options: FetchOptions<operations["listGroupProcessPerformanceAdvisorSlowQueryLogs"]>) {
549553
const { data, error, response } = await this.client.GET(
550554
"/api/atlas/v2/groups/{groupId}/processes/{processId}/performanceAdvisor/slowQueryLogs",
551555
options
@@ -557,7 +561,7 @@ export class ApiClient {
557561
}
558562

559563
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
560-
async listOrganizations(options?: FetchOptions<operations["listOrganizations"]>) {
564+
async listOrgs(options?: FetchOptions<operations["listOrgs"]>) {
561565
const { data, error, response } = await this.client.GET("/api/atlas/v2/orgs", options);
562566
if (error) {
563567
throw ApiClientError.fromError(response, error);
@@ -566,7 +570,7 @@ export class ApiClient {
566570
}
567571

568572
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
569-
async listOrganizationProjects(options: FetchOptions<operations["listOrganizationProjects"]>) {
573+
async getOrgGroups(options: FetchOptions<operations["getOrgGroups"]>) {
570574
const { data, error, response } = await this.client.GET("/api/atlas/v2/orgs/{orgId}/groups", options);
571575
if (error) {
572576
throw ApiClientError.fromError(response, error);

0 commit comments

Comments
 (0)