UNPKG

@apidevtools/swagger-parser

Version:

Swagger 2.0 and OpenAPI 3.0 parser and validator for Node and browsers

80 lines (71 loc) 2.89 kB
"use strict"; const util = require("util"); exports.format = util.format; exports.inherits = util.inherits; const parse = (u) => new URL(u); /** * Regular Expression that matches Swagger path params. */ exports.swaggerParamRegExp = /\{([^/}]+)}/g; /** * List of HTTP verbs used for OperationItem as per the Swagger specification */ const operationsList = ["get", "post", "put", "delete", "patch", "options", "head", "trace"]; /** * This function takes in a Server object, checks if it has relative path * and then fixes it as per the path url * * @param {object} server - The server object to be fixed * @param {string} path - The path (an http/https url) from where the file was downloaded * @returns {object} - The fixed server object */ function fixServers (server, path) { // Server url starting with "/" tells that it is not an http(s) url if (server.url && server.url.startsWith("/")) { const inUrl = parse(path); const finalUrl = inUrl.protocol + "//" + inUrl.hostname + server.url; server.url = finalUrl; return server; } } /** * This function helps fix the relative servers in the API definition file * be at root, path or operation's level */ function fixOasRelativeServers (schema, filePath) { if (schema.openapi && (filePath && (filePath.startsWith("http:") || filePath.startsWith("https:")))) { /** * From OpenAPI v3 spec for Server object's url property: "REQUIRED. A URL to the target host. * This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where * the OpenAPI document is being served." * Further, the spec says that "servers" property can show up at root level, in 'Path Item' object or in 'Operation' object. * However, interpretation of the spec says that relative paths for servers should take into account the hostname that * serves the OpenAPI file. */ if (schema.servers) { schema.servers.map(server => fixServers(server, filePath)); // Root level servers array's fixup } // Path, Operation, or Webhook level servers array's fixup ["paths", "webhooks"].forEach(component => { Object.keys(schema[component] || []).forEach(path => { const pathItem = schema[component][path]; Object.keys(pathItem).forEach(opItem => { if (opItem === "servers") { // servers at pathitem level pathItem[opItem].map(server => fixServers(server, filePath)); } else if (operationsList.includes(opItem)) { // servers at operation level if (pathItem[opItem].servers) { pathItem[opItem].servers.map(server => fixServers(server, filePath)); } } }); }); }); } else { // Do nothing and return } } exports.fixOasRelativeServers = fixOasRelativeServers;