Skip to content

Commit c333a45

Browse files
feat: Operation ID override support to transformation (#635)
Co-authored-by: Copilot <[email protected]>
1 parent 1cd9c0e commit c333a45

File tree

6 files changed

+74
-2
lines changed

6 files changed

+74
-2
lines changed

tools/transformer/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Additionally, framework enables us to extend it by additional rules per usage to
1616

1717
Transformations should be generic - they should be reusable across OpenAPI files and be generally an unopinionated way of
1818
handling OpenAPI file. That means that they would improve any public OpenAPI for.
19-
Parameters for transformations (actuall scripts) can be more finetuned to current OpenAPI file.
19+
Parameters for transformations (actual scripts) can be more finetuned to current OpenAPI file.
2020

2121
## Usage
2222

@@ -91,10 +91,14 @@ Enums in current form are hard to ensure backwards compatibility.
9191
This transformation removes all openapi `nullable` fields from the schema.
9292
Useful for situations for schemas where nullability handling is not desired.
9393

94+
6. Apply Operation ID Overrides
95+
96+
This transformation updates the operation IDs in the OpenAPI file if the operation has an `x-xgen-operation-id-override` extension. Then, it removes the Operation ID override extension from the OpenAPI file.
97+
9498
## Transformation Validation
9599

96100
Transformation engine does perform validation for invalid cases.
97-
If transformation fails it usualy means that OpenAPI file is not correct and has issues that require human attention.
101+
If transformation fails it usually means that OpenAPI file is not correct and has issues that require human attention.
98102

99103
The process of fixing OpenAPI always involves:
100104

tools/transformer/__tests__/input.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"get": {
3535
"description": "Info description.",
3636
"operationId": "versionedExample",
37+
"x-xgen-operation-id-override": "getVersionedExample",
3738
"responses": {
3839
"200": {
3940
"content": {

tools/transformer/__tests__/transformations.test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const {
44
applyModelNameTransformations,
55
transformAllOf,
66
transformOneOf,
7+
applyOperationIdOverrides,
78
} = require("../src/transformations");
89
const cases = require("./transformations-snapshots");
910

@@ -62,3 +63,16 @@ test("applyModelNameTransformations", () => {
6263
expect(modelKey.endsWith("View")).toBeFalsy();
6364
}
6465
});
66+
67+
test("applyOperationIdOverrides", () => {
68+
api = applyOperationIdOverrides(api);
69+
expect(
70+
api.paths["/api/atlas/v1.5/groups/{groupId}/clusters"].post.operationId,
71+
).toEqual("createCluster");
72+
expect(api.paths["/api/atlas/v2/example/info"].get.operationId).toEqual(
73+
"getVersionedExample",
74+
);
75+
expect(
76+
api.paths["/api/atlas/v2/example/info"].get["x-xgen-operation-id-override"],
77+
).toBeFalsy();
78+
});

tools/transformer/src/atlasTransformations.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const {
1010
removeRefsFromParameters,
1111
reorderResponseBodies,
1212
applyFieldTransformations,
13+
applyOperationIdOverrides,
1314
} = require("./transformations");
1415
const { resolveOpenAPIReference } = require("./engine/transformers");
1516

@@ -71,6 +72,8 @@ module.exports = function runTransformations(openapi) {
7172
"#/components/parameters/pretty",
7273
]);
7374

75+
openapi = applyOperationIdOverrides(openapi);
76+
7477
return openapi;
7578
};
7679

tools/transformer/src/transformations/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const { applyRemoveNullableTransformations } = require("./removeNullable");
1616
const { removeRefsFromParameters } = require("./removeInvalidParams");
1717
const { reorderResponseBodies } = require("./reorderResponseBodies");
1818
const { applyFieldTransformations } = require("./fields");
19+
const { applyOperationIdOverrides } = require("./operationId");
1920

2021
module.exports = {
2122
applyModelNameTransformations,
@@ -33,4 +34,5 @@ module.exports = {
3334
removeRefsFromParameters,
3435
reorderResponseBodies,
3536
applyFieldTransformations,
37+
applyOperationIdOverrides,
3638
};
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const OP_ID_OVERRIDE_EXTENSION = "x-xgen-operation-id-override";
2+
const validHttpMethods = [
3+
"get",
4+
"put",
5+
"post",
6+
"delete",
7+
"options",
8+
"head",
9+
"patch",
10+
"trace",
11+
];
12+
13+
/**
14+
* Replaces Operation IDs if operation ID overrides are present and removes the
15+
* override extension.
16+
*
17+
* @param {*} api OpenAPI JSON File
18+
* @returns {*} transformed OpenAPI JSON File
19+
*/
20+
function applyOperationIdOverrides(api) {
21+
const hasPaths = api && api.paths;
22+
if (!hasPaths) {
23+
throw new Error("Missing paths in openapi");
24+
}
25+
26+
Object.keys(api.paths).forEach((pathKey) => {
27+
const pathItem = api.paths[pathKey];
28+
if (!pathItem) {
29+
throw new Error("Missing path item in openapi");
30+
}
31+
32+
validHttpMethods.forEach((method) => {
33+
const operationItem = api.paths[pathKey][method];
34+
if (operationItem && operationItem[OP_ID_OVERRIDE_EXTENSION]) {
35+
// Update Operation ID based on override extension
36+
api.paths[pathKey][method].operationId =
37+
operationItem[OP_ID_OVERRIDE_EXTENSION];
38+
delete api.paths[pathKey][method][OP_ID_OVERRIDE_EXTENSION];
39+
}
40+
});
41+
});
42+
43+
return api;
44+
}
45+
46+
module.exports = {
47+
applyOperationIdOverrides,
48+
};

0 commit comments

Comments
 (0)