in packages/libs/oai2-to-oai3/src/converter.ts [87:273]
async convert() {
// process servers
if (this.original["x-ms-parameterized-host"]) {
const xMsPHost: any = this.original["x-ms-parameterized-host"];
const scheme =
xMsPHost.useSchemePrefix === false ? "" : (this.original.schemes || ["http"]).map((s) => s + "://")[0] || "";
const server: oai3.Server = {
url: scheme + xMsPHost.hostTemplate + (this.original.basePath || ""),
};
if (xMsPHost.positionInOperation) {
server["x-ms-parameterized-host"] = { positionInOperation: xMsPHost.positionInOperation };
}
server.variables = {};
for (const msp in xMsPHost.parameters) {
if (!msp.startsWith("x-")) {
let originalParameter: any = {};
const param: any = {};
if (xMsPHost.parameters[msp].$ref !== undefined) {
const parsedRef = parseOai2Ref(xMsPHost.parameters[msp].$ref);
if (parsedRef === undefined) {
throw new Error(`Reference ${xMsPHost.parameters[msp].$ref} is invalid. Check the syntax.`);
}
originalParameter = await this.resolveReference(parsedRef.file, parsedRef.path);
if (originalParameter === undefined) {
throw new Error(`Unable to resolve ${xMsPHost.parameters[msp].$ref}.`);
}
// $ref'd parameters should be client parameters
if (!originalParameter["x-ms-parameter-location"]) {
originalParameter["x-ms-parameter-location"] = "client";
}
originalParameter["x-ms-original"] = {
$ref: await this.convertReferenceToOai3(xMsPHost.parameters[msp].$ref),
};
} else {
originalParameter = xMsPHost.parameters[msp];
}
// TODO: Investigate why its not possible to copy
// properties and filter the property 'in' using
// object destructuring.
for (const key in originalParameter) {
switch (key) {
case "in":
case "required":
case "type":
case "format":
case "name":
// turn these into x-* properties
param[`x-${key}`] = originalParameter[key];
break;
default:
param[key] = originalParameter[key];
break;
}
}
const parameterName = originalParameter.name;
if (originalParameter.default === undefined) {
if (originalParameter.enum) {
param.default = originalParameter.enum[0];
} else {
param.default = "";
}
}
// don't have empty parameters
if (parameterName) {
server.variables[parameterName] = param;
}
}
}
this.generated.__set__("servers", this.newArray("/x-ms-parameterized-host"));
this.generated.servers!.__push__({ value: server, sourcePointer: "/x-ms-parameterized-host" });
} else if (this.original.host) {
if (this.generated.servers === undefined) {
this.generated.__set__("servers", this.newArray("/host"));
}
for (const { value: s, pointer } of visit(this.original.schemes)) {
const server: oai3.Server = {
url: (s ? s + ":" : "") + "//" + this.original.host + (this.original.basePath ? this.original.basePath : "/"),
};
extractServerParameters(server);
this.generated.servers?.__push__({ value: server, sourcePointer: pointer });
}
} else if (this.original.basePath) {
const server: any = {};
server.url = this.original.basePath;
extractServerParameters(server);
if (this.generated.servers === undefined) {
this.generated.__set__("servers", this.newArray("/basePath"));
}
this.generated.servers!.__push__({ value: server, sourcePointer: "/basePath" });
}
if (this.generated.servers === undefined) {
this.generated.__set__("servers", { value: [], sourcePointer: NoMapping });
}
// internal function to extract server parameters
function extractServerParameters(server) {
server.url = server.url.split("{{").join("{");
server.url = server.url.split("}}").join("}");
server.url.replace(/\{(.+?)\}/g, function (match, group1) {
if (!server.variables) {
server.variables = {};
}
server.variables[group1] = { default: "unknown" };
});
}
// extract cosumes and produces
const globalProduces = this.original.produces ? this.original.produces : ["*/*"];
const globalConsumes = this.original.consumes ? this.original.consumes : ["application/json"];
for (const { value, key, pointer, children } of visit(this.original)) {
switch (key) {
case "swagger":
this.generated.__set__("openapi", { value: "3.0.0", sourcePointer: pointer });
break;
case "info":
this.generated.__set__("info", this.newObject(pointer));
await this.visitInfo(children);
break;
case "x-ms-paths":
case "paths":
{
if (!this.generated[key]) {
this.generated.__set__(key, this.newObject(pointer));
}
await this.visitPaths(this.generated[key], children, globalConsumes, globalProduces);
}
break;
case "host":
case "basePath":
case "schemes":
case "x-ms-parameterized-host":
// host, basePath and schemes already processed
break;
case "consumes":
case "produces":
// PENDING
break;
case "definitions":
await this.visitDefinitions(children);
break;
case "parameters":
await this.visitParameterDefinitions(children);
break;
case "responses":
if (!this.generated.components) {
this.generated.__set__("components", this.newObject(pointer));
}
this.generated.components?.__set__("responses", this.newObject(pointer));
await this.visitResponsesDefinitions(children, globalProduces);
break;
case "securityDefinitions":
if (!this.generated.components) {
this.generated.__set__("components", this.newObject(pointer));
}
this.generated.components?.__set__("securitySchemes", this.newObject(pointer));
await this.visitSecurityDefinitions(children);
break;
// no changes to security from OA2 to OA3
case "security":
this.generated.__set__("security", { value, sourcePointer: pointer });
break;
case "tags":
this.generated.__set__("tags", this.newArray(pointer));
await this.visitTags(this.generated.tags!, children);
break;
case "externalDocs":
this.visitExternalDocs(this.generated, key, value, pointer);
break;
default:
// handle stuff liks x-* and things not recognized
await this.visitExtensions(this.generated, key, value, pointer);
break;
}
}
return this.generated;
}