forked from matrix-org/matrix-spec
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create Swagger 2.0 to OpenAPI 3.1 conversion scripts
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
- Loading branch information
Showing
6 changed files
with
1,646 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
"use strict"; | ||
import fs from 'node:fs/promises'; | ||
import converter from 'swagger2openapi'; | ||
import path_utils from 'node:path'; | ||
import yaml from 'yaml'; | ||
|
||
import { applyObjectFixes } from './object-fixes.mjs'; | ||
|
||
async function getStartComment(path) { | ||
const file = await fs.open(path); | ||
|
||
let start_comment = ""; | ||
for await (const line of file.readLines()) { | ||
if (line.startsWith('#')) { | ||
start_comment += line + '\n'; | ||
} else { | ||
break; | ||
} | ||
}; | ||
|
||
await file.close(); | ||
|
||
return start_comment | ||
} | ||
|
||
async function convertDefinitionsFile(path) { | ||
let relative_separator = path.lastIndexOf('/data/api'); | ||
let short_path = path.slice(relative_separator + 1); | ||
console.log("%s", short_path); | ||
|
||
// Save the comments at the start of the file to not lose them. | ||
let start_comment = await getStartComment(path); | ||
|
||
// Convert. | ||
const options = await converter.convertFile(path, { | ||
// Patch fixable errors. | ||
patch: true, | ||
// Keep $ref siblings. | ||
refSiblings: 'preserve', | ||
// Don't deduplicate requestBodies. | ||
resolveInternal: true, | ||
// Write OpenAPI version 3.1.0, even if it's not completely true, it'll | ||
// be fixed later. | ||
targetVersion: '3.1.0', | ||
}); | ||
|
||
// Apply fixes on object. | ||
const obj = applyObjectFixes(options.openapi); | ||
|
||
// Serialize. | ||
const doc = new yaml.Document(obj); | ||
const content = yaml.stringify(doc, { | ||
// Use "literal" blocks, like the input. | ||
blockQuote: "literal" | ||
}); | ||
|
||
// Save to file. | ||
await fs.writeFile(path, start_comment + content); | ||
} | ||
|
||
export async function convertDefinitionsDir(path) { | ||
console.log("Converting files in %s", path); | ||
|
||
const files = await fs.readdir(path); | ||
|
||
for (const file of files) { | ||
if (file.endsWith(".yaml")) { | ||
await convertDefinitionsFile(path_utils.join(path, file)); | ||
} | ||
} | ||
} | ||
|
||
// Convert Swagger 2.0 definitions to OpenAPI 3.0.0. | ||
export async function convertDefinitions(path) { | ||
// We don't want to try to convert schemas in subdirectories, so we need to | ||
// call this separately for every directory inside `data/api`. | ||
let api_dir = path_utils.join(path, "api"); | ||
const files = await fs.readdir(api_dir); | ||
|
||
for (const file of files) { | ||
await convertDefinitionsDir(path_utils.join(api_dir, file)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
"use strict"; | ||
import nopt from 'nopt'; | ||
|
||
import { convertDefinitions } from './convert-definitions.mjs'; | ||
import { applyStringFixes } from './string-fixes.mjs'; | ||
|
||
const opts = nopt({ | ||
"help": Boolean, | ||
"data": String | ||
}, { | ||
"h": "--help", | ||
"d": "--data" | ||
}); | ||
|
||
console.log("params: {}", opts); | ||
if (opts.help) { | ||
console.log( | ||
"Convert the definitions from Swagger 2.0 to OpenAPI 3.0\n" + | ||
"Usage:\n" + | ||
" node index.mjs -d <data_folder>" | ||
); | ||
process.exit(0); | ||
} | ||
if (!opts.data) { | ||
console.error("No [d]ata dir specified."); | ||
process.exit(1); | ||
} | ||
|
||
console.log("Converting Swagger 2.0 definitions to OpenAPI 3.0 in %s...", opts.data); | ||
try { | ||
await convertDefinitions(opts.data); | ||
|
||
console.log("Applying string fixes..."); | ||
await applyStringFixes(opts.data); | ||
|
||
console.log(" ✅ Success"); | ||
} catch (err) { | ||
console.error(' ❌ {}', err); | ||
process.exit(1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
"use strict"; | ||
import { URL } from 'node:url'; | ||
|
||
// Refactor `servers` field to be able to access `basePath` easily. | ||
function refactorServers(obj) { | ||
if (!obj.servers) { | ||
return; | ||
} | ||
|
||
let server = { | ||
url: "", | ||
variables: { | ||
protocol: {}, | ||
hostname: { | ||
default: "" | ||
}, | ||
basePath: { | ||
default: "" | ||
} | ||
} | ||
} | ||
|
||
const url = new URL(obj.servers[0].url); | ||
|
||
if (obj.servers.length > 1) { | ||
// In our case several URLs always mean both http and https for the same | ||
// host. | ||
obj.servers.pop() | ||
} | ||
|
||
server.url = "{protocol}://{hostname}{basePath}" | ||
server.variables.protocol = { | ||
enum: ["http", "https"], | ||
default: "https", | ||
} | ||
server.variables.hostname.default = url.host | ||
server.variables.basePath.default = url.pathname | ||
|
||
obj.servers[0] = server; | ||
|
||
return obj; | ||
} | ||
|
||
// Fixes to apply to a converted schema object. | ||
export function applyObjectFixes(obj) { | ||
obj = refactorServers(obj); | ||
|
||
return obj; | ||
} |
Oops, something went wrong.