-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathprocess-openapi-specs.cjs
More file actions
executable file
·263 lines (217 loc) · 8.65 KB
/
process-openapi-specs.cjs
File metadata and controls
executable file
·263 lines (217 loc) · 8.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
/**
* Process OpenAPI specs by filtering out write APIs, deprecated APIs, and ignored services
* Usage: node process-openapi-specs.cjs [input-folder] [output-folder]
*
* Features:
* - Filters out write operations (POST, PUT, PATCH, DELETE)
* - Filters out deprecated APIs
* - Removes host field from specs
* - Removes externalDocs field from specs
* - Removes x-docs field from specs
* - Removes realm field from x-version
* - Ignores specified services (buildinfo, challenge, differ, eventlog, matchmaking, sessionbrowser, ugc)
* - Prettifies JSON output
*/
// Default paths
const DEFAULT_INPUT_FOLDER = '../justice-codegen-sdk-spec/spec/stage_main';
const DEFAULT_OUTPUT_FOLDER = './openapi-specs';
// const FILTERED_METHODS = ['post', 'put', 'patch', 'delete'];
const FILTERED_METHODS = [];
// Services to be ignored during processing (by filename without extension)
const IGNORED_SERVICES = [
'buildinfo',
'challenge',
'differ',
'eventlog',
'matchmaking',
'sessionbrowser',
'ugc'
];
function parseArguments() {
const args = process.argv.slice(2);
const inputFolder = args[0] || DEFAULT_INPUT_FOLDER;
const outputFolder = args[1] || DEFAULT_OUTPUT_FOLDER;
return { inputFolder, outputFolder };
}
function ensureDirectoryExists(dirPath) {
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
console.log(`Created directory: ${dirPath}`);
}
}
function isJsonFile(filename) {
return path.extname(filename).toLowerCase() === '.json';
}
function shouldIgnoreFile(filename) {
const baseName = path.basename(filename, '.json').toLowerCase();
return IGNORED_SERVICES.includes(baseName);
}
function filterPaths(paths) {
const filteredPaths = {};
for (const [pathKey, pathValue] of Object.entries(paths)) {
const filteredMethods = {};
let hasValidMethods = false;
for (const [method, methodValue] of Object.entries(pathValue)) {
// Skip write methods
if (FILTERED_METHODS.includes(method.toLowerCase())) {
console.log(` Filtered out ${method.toUpperCase()} ${pathKey}`);
continue;
}
// Skip deprecated APIs
if (methodValue && methodValue.deprecated === true) {
console.log(` Filtered out ${method.toUpperCase()} ${pathKey} (deprecated)`);
continue;
}
// Keep this method
filteredMethods[method] = methodValue;
hasValidMethods = true;
}
// Only include the path if it has valid methods
if (hasValidMethods) {
filteredPaths[pathKey] = filteredMethods;
}
}
return filteredPaths;
}
function processOpenApiSpec(inputPath, outputPath) {
try {
console.log(`Processing: ${inputPath}`);
// Read and parse JSON
const rawData = fs.readFileSync(inputPath, 'utf8');
const spec = JSON.parse(rawData);
// Track original counts
const originalPathCount = spec.paths ? Object.keys(spec.paths).length : 0;
let originalMethodCount = 0;
if (spec.paths) {
for (const pathMethods of Object.values(spec.paths)) {
originalMethodCount += Object.keys(pathMethods).length;
}
}
// Filter paths
if (spec.paths) {
spec.paths = filterPaths(spec.paths);
}
// Remove host field if it exists
if (spec.host) {
delete spec.host;
console.log(' Removed top-level host field');
}
// Remove externalDocs field if it exists
if (spec.externalDocs) {
delete spec.externalDocs;
console.log(' Removed externalDocs field');
}
// Remove x-docs field if it exists
if (spec['x-docs']) {
delete spec['x-docs'];
console.log(' Removed x-docs field');
}
// Remove realm field from x-version if it exists
if (spec['x-version'] && spec['x-version'].realm) {
delete spec['x-version'].realm;
console.log(' Removed realm field from x-version');
}
// Calculate filtered counts
const filteredPathCount = spec.paths ? Object.keys(spec.paths).length : 0;
let filteredMethodCount = 0;
if (spec.paths) {
for (const pathMethods of Object.values(spec.paths)) {
filteredMethodCount += Object.keys(pathMethods).length;
}
}
// Prettify and write JSON
const prettyJson = JSON.stringify(spec, null, 2);
fs.writeFileSync(outputPath, prettyJson, 'utf8');
console.log(` ✓ Processed: ${path.basename(inputPath)}`);
console.log(` Paths: ${originalPathCount} → ${filteredPathCount}`);
console.log(` Methods: ${originalMethodCount} → ${filteredMethodCount}`);
console.log(` Output: ${outputPath}`);
console.log('');
return {
originalPaths: originalPathCount,
filteredPaths: filteredPathCount,
originalMethods: originalMethodCount,
filteredMethods: filteredMethodCount
};
} catch (error) {
console.error(`Error processing ${inputPath}:`, error.message);
return null;
}
}
function main() {
const { inputFolder, outputFolder } = parseArguments();
console.log('OpenAPI Spec Processor');
console.log('=====================');
console.log(`Input folder: ${path.resolve(inputFolder)}`);
console.log(`Output folder: ${path.resolve(outputFolder)}`);
console.log('');
// Check if input folder exists
if (!fs.existsSync(inputFolder)) {
console.error(`Error: Input folder does not exist: ${inputFolder}`);
process.exit(1);
}
// Ensure output directory exists
ensureDirectoryExists(outputFolder);
// Get all JSON files in input folder
const files = fs.readdirSync(inputFolder);
const allJsonFiles = files.filter(isJsonFile);
const jsonFiles = allJsonFiles.filter(file => !shouldIgnoreFile(file));
const ignoredFiles = allJsonFiles.filter(shouldIgnoreFile);
if (allJsonFiles.length === 0) {
console.log('No JSON files found in input folder.');
return;
}
console.log(`Found ${allJsonFiles.length} JSON file(s), processing ${jsonFiles.length}:`);
jsonFiles.forEach(file => console.log(` - ${file}`));
if (ignoredFiles.length > 0) {
console.log(`\nIgnored ${ignoredFiles.length} file(s):`);
ignoredFiles.forEach(file => console.log(` - ${file} (ignored service)`));
}
console.log('');
// Process each JSON file
const results = [];
let totalOriginalPaths = 0;
let totalFilteredPaths = 0;
let totalOriginalMethods = 0;
let totalFilteredMethods = 0;
for (const file of jsonFiles) {
const inputPath = path.join(inputFolder, file);
const outputPath = path.join(outputFolder, file);
const result = processOpenApiSpec(inputPath, outputPath);
if (result) {
results.push({ file, ...result });
totalOriginalPaths += result.originalPaths;
totalFilteredPaths += result.filteredPaths;
totalOriginalMethods += result.originalMethods;
totalFilteredMethods += result.filteredMethods;
}
}
// Summary
console.log('Processing Summary');
console.log('==================');
console.log(`Files found: ${allJsonFiles.length}`);
console.log(`Files ignored: ${ignoredFiles.length} (${IGNORED_SERVICES.join(', ')})`);
console.log(`Files processed: ${results.length}/${jsonFiles.length}`);
console.log(`Total paths: ${totalOriginalPaths} → ${totalFilteredPaths} (${totalOriginalPaths - totalFilteredPaths} removed)`);
console.log(`Total methods: ${totalOriginalMethods} → ${totalFilteredMethods} (${totalOriginalMethods - totalFilteredMethods} removed)`);
console.log('');
console.log('Filtering criteria:');
console.log(` - Ignored services: ${IGNORED_SERVICES.join(', ')}`);
console.log(` - Removed filtered methods: ${FILTERED_METHODS.join(', ').toUpperCase()}`);
console.log(' - Removed deprecated APIs');
console.log('');
console.log('✓ Processing complete!');
}
if (require.main === module) {
main();
}
module.exports = {
processOpenApiSpec,
filterPaths,
shouldIgnoreFile,
FILTERED_METHODS,
IGNORED_SERVICES
};