Skip to content

Commit 1231d61

Browse files
committed
Preprocessing - Consolidate global parameters into GlobalParams schema
Signed-off-by: xil <fridalu66@gmail.com>
1 parent 14c4f33 commit 1231d61

3 files changed

Lines changed: 165 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
1010
- Preprocessing: Handle unnamed additionalProperties.([#272](https://github.com/opensearch-project/opensearch-protobufs/pull/272))
1111
- Support importing without proto file name knowledge in Python generated protobuf code ([#275](https://github.com/opensearch-project/opensearch-protobufs/pull/275))
1212
- Preprocessing - Add filter to not convert additionalProperties when only one key allowed ([#292](https://github.com/opensearch-project/opensearch-protobufs/pull/292))
13+
- Preprocessing - Consolidate global parameters into GlobalParams schema ([#293](https://github.com/opensearch-project/opensearch-protobufs/pull/293))
1314

1415
### Changed
1516
- Update preprocessing for x-protobuf-excluded ([#266](https://github.com/opensearch-project/opensearch-protobufs/pull/266))
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
import { OpenAPIV3 } from 'openapi-types';
2+
3+
export class GlobalParameterConsolidator {
4+
private root: OpenAPIV3.Document;
5+
private globalParamRefs: Set<string> = new Set();
6+
private globalParamDefinitions: Map<string, any> = new Map();
7+
8+
constructor(root: OpenAPIV3.Document) {
9+
this.root = root;
10+
}
11+
12+
/**
13+
* Consolidates global query parameters into a single globalParams object.
14+
*
15+
*/
16+
consolidate(): OpenAPIV3.Document {
17+
this.discoverGlobalParameters();
18+
19+
if (this.globalParamRefs.size === 0) {
20+
console.log('No global parameters found');
21+
return this.root;
22+
}
23+
24+
this.createGlobalParamsSchema();
25+
26+
this.createGlobalParamsParameter();
27+
28+
this.replaceGlobalParamsInPaths();
29+
30+
return this.root;
31+
}
32+
33+
/**
34+
* Check all parameters marked with x-global: true
35+
*/
36+
private discoverGlobalParameters(): void {
37+
if (!this.root.components?.parameters) {
38+
return;
39+
}
40+
41+
// Check parameters for x-global: true
42+
for (const [paramKey, paramDef] of Object.entries(this.root.components.parameters)) {
43+
if (!paramDef) continue;
44+
45+
const param = paramDef as any;
46+
if (param['x-global'] === true || param['x-global'] === 'true') {
47+
const paramRef = `#/components/parameters/${paramKey}`;
48+
this.globalParamRefs.add(paramRef);
49+
this.globalParamDefinitions.set(paramKey, param);
50+
console.log(`Found global parameter: ${paramKey}`);
51+
}
52+
}
53+
}
54+
55+
private createGlobalParamsSchema(): void {
56+
if (!this.root.components) {
57+
this.root.components = {};
58+
}
59+
if (!this.root.components.schemas) {
60+
this.root.components.schemas = {};
61+
}
62+
63+
const properties: Record<string, any> = {};
64+
65+
for (const [paramKey, paramDef] of this.globalParamDefinitions) {
66+
const paramName = paramDef.name || paramKey;
67+
const schema = paramDef.schema || {};
68+
69+
const propertyObj: any = {
70+
...schema,
71+
description: paramDef.description || schema.description,
72+
};
73+
74+
for (const key in paramDef) {
75+
if (key.startsWith('x-')) {
76+
propertyObj[key] = paramDef[key];
77+
}
78+
}
79+
80+
properties[paramName] = propertyObj;
81+
}
82+
83+
const globalParamsSchema: OpenAPIV3.SchemaObject = {
84+
type: 'object',
85+
description: 'Global query parameters that apply to all operations',
86+
properties,
87+
};
88+
89+
(this.root.components.schemas as any).GlobalParams = globalParamsSchema;
90+
}
91+
92+
private createGlobalParamsParameter(): void {
93+
if (!this.root.components) {
94+
this.root.components = {};
95+
}
96+
if (!this.root.components.parameters) {
97+
this.root.components.parameters = {};
98+
}
99+
100+
const globalParamsParam: any = {
101+
name: 'globalParams',
102+
in: 'query',
103+
description: 'Global query parameters',
104+
schema: {
105+
$ref: '#/components/schemas/GlobalParams',
106+
},
107+
'x-global': true,
108+
};
109+
110+
(this.root.components.parameters as any).globalParams = globalParamsParam;
111+
}
112+
113+
private replaceGlobalParamsInPaths(): void {
114+
if (!this.root.paths) {
115+
return;
116+
}
117+
118+
for (const pathKey in this.root.paths) {
119+
const pathItem = this.root.paths[pathKey];
120+
if (!pathItem) continue;
121+
122+
const methods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head', 'trace'];
123+
for (const method of methods) {
124+
const operation = (pathItem as any)[method] as OpenAPIV3.OperationObject | undefined;
125+
if (!operation) continue;
126+
127+
this.replaceGlobalParamsInOperation(operation);
128+
}
129+
}
130+
}
131+
132+
private replaceGlobalParamsInOperation(operation: OpenAPIV3.OperationObject): void {
133+
if (!operation.parameters) {
134+
return;
135+
}
136+
137+
const indicesToRemove: number[] = [];
138+
let hasGlobalParams = false;
139+
140+
for (let i = 0; i < operation.parameters.length; i++) {
141+
const param = operation.parameters[i];
142+
const paramRef = (param as any).$ref;
143+
144+
if (paramRef && this.globalParamRefs.has(paramRef)) {
145+
indicesToRemove.push(i);
146+
hasGlobalParams = true;
147+
}
148+
}
149+
150+
for (let i = indicesToRemove.length - 1; i >= 0; i--) {
151+
operation.parameters.splice(indicesToRemove[i], 1);
152+
}
153+
154+
if (hasGlobalParams) {
155+
const globalParamsRef: OpenAPIV3.ReferenceObject = {
156+
$ref: '#/components/parameters/globalParams',
157+
};
158+
operation.parameters.push(globalParamsRef as any);
159+
}
160+
}
161+
}

tools/proto-convert/src/PreProcessing.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Logger from './utils/logger';
66
import * as path from 'path';
77
import {SchemaModifier} from "./SchemaModifier";
88
import {VendorExtensionProcessor} from "./VendorExtensionProcessor";
9+
import {GlobalParameterConsolidator} from "./GlobalParamWrapper";
910
import type {OpenAPIV3} from "openapi-types";
1011

1112
let config_filtered_path: string[] | undefined;
@@ -49,7 +50,8 @@ try {
4950
const original_spec = read_yaml(opts.input)
5051
const filtered_spec = new Filter().filter_spec(original_spec, opts.filtered_path);
5152
const sanitized_spec = new Sanitizer().sanitize(filtered_spec);
52-
const vendor_processed_spec = new VendorExtensionProcessor(sanitized_spec, logger).process();
53+
const consolidated_spec = new GlobalParameterConsolidator(sanitized_spec).consolidate();
54+
const vendor_processed_spec = new VendorExtensionProcessor(consolidated_spec, logger).process();
5355
const schema_modified_spec = new SchemaModifier(vendor_processed_spec, logger).modify();
5456
write_yaml(opts.output, schema_modified_spec);
5557

0 commit comments

Comments
 (0)