Skip to content

Commit 2f22fe7

Browse files
author
Phil Sturgeon
authored
Merge pull request #181 from jaishirole/main
Fix for issue#153-relative server paths in OpenAPI
2 parents e3a09bd + f8b769b commit 2f22fe7

8 files changed

+18915
-180
lines changed

lib/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ SwaggerParser.prototype.parse = async function (path, api, options, callback) {
9797
`Swagger Parser only supports versions ${supportedVersions.join(", ")}`
9898
);
9999
}
100+
101+
// This is an OpenAPI v3 schema, check if the "servers" have any relative paths and
102+
// fix them if the content was pulled from a web resource
103+
util.fixOasRelativeServers(schema, args.path);
100104
}
101105

102106
// Looks good!

lib/util.js

+66
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use strict";
22

33
const util = require("util");
4+
const url = require("@apidevtools/json-schema-ref-parser/lib/util/url");
45

56
exports.format = util.format;
67
exports.inherits = util.inherits;
@@ -9,3 +10,68 @@ exports.inherits = util.inherits;
910
* Regular Expression that matches Swagger path params.
1011
*/
1112
exports.swaggerParamRegExp = /\{([^/}]+)}/g;
13+
14+
/**
15+
* List of HTTP verbs used for OperationItem as per the Swagger specification
16+
*/
17+
const operationsList = ["get", "post", "put", "delete", "patch", "options", "head", "trace"];
18+
19+
/**
20+
* This function takes in a Server object, checks if it has relative path
21+
* and then fixes it as per the path url
22+
*
23+
* @param {object} server - The server object to be fixed
24+
* @param {string} path - The path (an http/https url) from where the file was downloaded
25+
* @returns {object} - The fixed server object
26+
*/
27+
function fixServers (server, path) {
28+
// Server url starting with "/" tells that it is not an http(s) url
29+
if (server.url && server.url.startsWith("/")) {
30+
const inUrl = url.parse(path);
31+
const finalUrl = inUrl.protocol + "//" + inUrl.hostname + server.url;
32+
server.url = finalUrl;
33+
return server;
34+
}
35+
}
36+
37+
/**
38+
* This function helps fix the relative servers in the API definition file
39+
* be at root, path or operation's level
40+
*/
41+
function fixOasRelativeServers (schema, filePath) {
42+
if (schema.openapi && (filePath && (filePath.startsWith("http:") || filePath.startsWith("https:")))) {
43+
/**
44+
* From OpenAPI v3 spec for Server object's url property: "REQUIRED. A URL to the target host.
45+
* This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where
46+
* the OpenAPI document is being served."
47+
* Further, the spec says that "servers" property can show up at root level, in 'Path Item' object or in 'Operation' object.
48+
* However, interpretation of the spec says that relative paths for servers should take into account the hostname that
49+
* serves the OpenAPI file.
50+
*/
51+
if (schema.servers) {
52+
schema.servers.map(server => fixServers(server, filePath)); // Root level servers array's fixup
53+
}
54+
55+
// Path or Operation level servers array's fixup
56+
Object.keys(schema.paths).forEach(path => {
57+
const pathItem = schema.paths[path];
58+
Object.keys(pathItem).forEach(opItem => {
59+
if (opItem === "servers") {
60+
// servers at pathitem level
61+
pathItem[opItem].map(server => fixServers(server, filePath));
62+
}
63+
else if (operationsList.includes(opItem)) {
64+
// servers at operation level
65+
if (pathItem[opItem].servers) {
66+
pathItem[opItem].servers.map(server => fixServers(server, filePath));
67+
}
68+
}
69+
});
70+
});
71+
}
72+
else {
73+
// Do nothing and return
74+
}
75+
}
76+
77+
exports.fixOasRelativeServers = fixOasRelativeServers;

0 commit comments

Comments
 (0)