async convert()

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;
  }