Skip to content

Commit a92f479

Browse files
committed
Resolved failing lint errors
1 parent 28ac37f commit a92f479

File tree

3 files changed

+90
-72
lines changed

3 files changed

+90
-72
lines changed

lib/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ SwaggerParser.prototype.parse = async function (path, api, options, callback) {
9898
);
9999
}
100100

101-
// This is an OpenAPI v3 schema, check if the "servers" have any relative paths and
101+
// This is an OpenAPI v3 schema, check if the "servers" have any relative paths and
102102
// fix them if the content was pulled from a web resource
103-
await util.fixOasRelativeServers(schema,args.path);
103+
util.fixOasRelativeServers(schema, args.path);
104104
}
105105

106106
// Looks good!

lib/util.js

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

33
const util = require("util");
4-
const {URL} = require('url');
4+
const { URL } = require("url");
55

66
exports.format = util.format;
77
exports.inherits = util.inherits;
@@ -14,47 +14,60 @@ exports.swaggerParamRegExp = /\{([^/}]+)}/g;
1414
/**
1515
* List of HTTP verbs used for OperationItem as per the Swagger specification
1616
*/
17-
const operationsList = ['get','post','put','delete','patch','options','head','trace'];
18-
19-
const fixServersFn = function (server,path) {
20-
//Server url starting with '/' tells that it is not an http(s) url
21-
if (server.url?.startsWith("/")) {
22-
const inUrl = new URL(path);
23-
var finalUrl = inUrl.protocol + "//" + inUrl.hostname + server.url;
24-
server.url = finalUrl;
25-
return server;
26-
}
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?.startsWith("/")) {
30+
const inUrl = new URL(path);
31+
const finalUrl = inUrl.protocol + "//" + inUrl.hostname + server.url;
32+
server.url = finalUrl;
33+
return server;
34+
}
2735
}
28-
async function fixOasRelativeServers(schema,filePath) {
29-
if (schema?.openapi && (filePath?.startsWith("http:") || filePath?.startsWith("https:"))) {
30-
/**
31-
* From OpenAPI v3 spec for Server object's url property: "REQUIRED. A URL to the target host.
32-
* This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where
33-
* the OpenAPI document is being served.""
34-
*
35-
* Further, the spec says that "servers" property can show up at root level, in 'Path Item' object or in 'Operation' object.
36-
* However, interpretation of the spec says that relative paths for servers should take into account the hostname that
37-
* serves the OpenAPI file.
38-
*/
39-
// Root level servers array's fixup
40-
schema.servers?.map(server => fixServersFn(server,filePath));
41-
42-
// Path or Operation level servers array's fixup
43-
Object.keys(schema.paths).forEach(path => {
44-
const pathItem = schema.paths[path];
45-
Object.keys(pathItem).forEach(opItem => {
46-
if(opItem === "servers"){
47-
//servers at pathitem level
48-
pathItem[opItem].map(server => fixServersFn(server,filePath));
49-
}else if(operationsList.includes(opItem)){
50-
//servers at operation level
51-
pathItem[opItem].servers?.map(server => fixServersFn(server,filePath));
52-
}
53-
});
54-
});
55-
} else {
56-
//Do nothing and return
57-
}
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?.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+
schema.servers?.map(server => fixServers(server, filePath)); // Root level servers array's fixup
52+
53+
// Path or Operation level servers array's fixup
54+
Object.keys(schema.paths).forEach(path => {
55+
const pathItem = schema.paths[path];
56+
Object.keys(pathItem).forEach(opItem => {
57+
if (opItem === "servers") {
58+
// servers at pathitem level
59+
pathItem[opItem].map(server => fixServers(server, filePath));
60+
}
61+
else if (operationsList.includes(opItem)) {
62+
// servers at operation level
63+
pathItem[opItem].servers?.map(server => fixServers(server, filePath));
64+
}
65+
});
66+
});
67+
}
68+
else {
69+
// Do nothing and return
70+
}
5871
}
5972

60-
exports.fixOasRelativeServers = fixOasRelativeServers;
73+
exports.fixOasRelativeServers = fixOasRelativeServers;

test/specs/oas-relative-servers/v3-relative-servers.spec.js

+33-28
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,95 @@
11
"use strict";
22

33
const SwaggerParser = require("../../../lib");
4-
const {expect} = require("chai");
4+
const { expect } = require("chai");
55
const path = require("../../utils/path");
66
const $RefParser = require("@apidevtools/json-schema-ref-parser");
77
const sinon = require("sinon");
88

9-
//Import of our fixed OpenAPI JSON files
9+
// Import of our fixed OpenAPI JSON files
1010
const v3RelativeServerJson = require("./v3-relative-server.json");
1111
const v3RelativeServerPathsOpsJson = require("./v3-relative-server-paths-ops.json");
1212
const v3NonRelativeServerJson = require("./v3-non-relative-server.json");
1313

14-
//Petstore v3 json has relative path in "servers"
14+
// Petstore v3 json has relative path in "servers"
1515
const RELATIVE_SERVERS_OAS3_URL_1 = "https://petstore3.swagger.io/api/v3/openapi.json";
1616

17-
//This will have "servers" at paths & operations level
18-
const RELATIVE_SERVERS_OAS3_URL_2 = "https://foo.my.cloud/v1/petstore/relativeservers";
17+
// This will have "servers" at paths & operations level
18+
const RELATIVE_SERVERS_OAS3_URL_2 = "https://foo.my.cloud/v1/petstore/relativeservers";
1919

20-
describe("Servers with relative paths in OpenAPI v3 files",() => {
20+
describe("Servers with relative paths in OpenAPI v3 files", () => {
2121
let mockParse;
22-
before(function () {
23-
//Mock the parse function
24-
mockParse = sinon.stub($RefParser.prototype,'parse');
22+
23+
before(() => {
24+
// Mock the parse function
25+
mockParse = sinon.stub($RefParser.prototype, "parse");
2526
});
2627

27-
after(function () {
28-
//Restore the parse function
28+
after(() => {
29+
// Restore the parse function
2930
$RefParser.prototype.parse.restore();
3031
});
3132

32-
it("should fix relative servers path in the file fetched from url",async()=>{
33+
it("should fix relative servers path in the file fetched from url", async () => {
3334
try {
3435
mockParse.callsFake(() => {
35-
//to prevent edit of the original JSON
36+
// to prevent edit of the original JSON
3637
return JSON.parse(JSON.stringify(v3RelativeServerJson));
3738
});
3839
let apiJson = await SwaggerParser.parse(RELATIVE_SERVERS_OAS3_URL_1);
3940
expect(apiJson.servers[0].url).to.equal("https://petstore3.swagger.io/api/v3");
40-
}catch (error) {
41-
console.error("\n\nError in relative servers at root test case:",error);
41+
}
42+
catch (error) {
43+
console.error("\n\nError in relative servers at root test case:", error);
4244
throw error;
4345
}
4446
});
4547

46-
it("should fix relative servers at root, path and operations level in the file fetched from url",async()=>{
48+
it("should fix relative servers at root, path and operations level in the file fetched from url", async () => {
4749
try {
4850
mockParse.callsFake(() => {
49-
//to prevent edit of the original JSON
51+
// to prevent edit of the original JSON
5052
return JSON.parse(JSON.stringify(v3RelativeServerPathsOpsJson));
5153
});
5254
let apiJson = await SwaggerParser.parse(RELATIVE_SERVERS_OAS3_URL_2);
5355
expect(apiJson.servers[0].url).to.equal("https://foo.my.cloud/api/v3");
5456
expect(apiJson.paths["/pet"].servers[0].url).to.equal("https://foo.my.cloud/api/v4");
55-
expect(apiJson.paths["/pet"]["get"].servers[0].url).to.equal("https://foo.my.cloud/api/v5");
56-
}catch (error) {
57-
console.error("\n\nError in relative servers at root test case:",error);
57+
expect(apiJson.paths["/pet"]?.get.servers[0].url).to.equal("https://foo.my.cloud/api/v5");
58+
}
59+
catch (error) {
60+
console.error("\n\nError in relative servers at root, path and operations test case:", error);
5861
throw error;
5962
}
6063
});
6164

62-
it("should parse but no change to relative servers path in local file import",async()=>{
65+
it("should parse but no change to relative servers path in local file import", async () => {
6366
try {
6467
mockParse.callsFake(() => {
6568
return JSON.parse(JSON.stringify(v3RelativeServerPathsOpsJson));
6669
});
6770
let apiJson = await SwaggerParser.parse(path.rel("./v3-relative-server.json"));
6871
expect(apiJson.servers[0].url).to.equal("/api/v3");
6972
expect(apiJson.paths["/pet"].servers[0].url).to.equal("/api/v4");
70-
expect(apiJson.paths["/pet"]["get"].servers[0].url).to.equal("/api/v5");
71-
}catch (error) {
72-
console.error("\n\nError in relative servers at root test case:",error);
73+
expect(apiJson.paths["/pet"]?.get.servers[0].url).to.equal("/api/v5");
74+
}
75+
catch (error) {
76+
console.error("\n\nError in relative servers at root but local file import test case:", error);
7377
throw error;
7478
}
7579
});
7680

77-
it("should parse but no change to non-relative servers path in local file import",async()=>{
81+
it("should parse but no change to non-relative servers path in local file import", async () => {
7882
try {
7983
mockParse.callsFake(() => {
8084
return JSON.parse(JSON.stringify(v3NonRelativeServerJson));
8185
});
8286
let apiJson = await SwaggerParser.parse(path.rel("./v3-non-relative-server.json"));
8387
expect(apiJson.servers[0].url).to.equal("https://petstore3.swagger.com/api/v3");
8488
expect(apiJson.paths["/pet"].servers[0].url).to.equal("https://petstore3.swagger.com/api/v4");
85-
expect(apiJson.paths["/pet"]["get"].servers[0].url).to.equal("https://petstore3.swagger.com/api/v5");
86-
}catch (error) {
87-
console.error("\n\nError in relative servers at root test case:",error);
89+
expect(apiJson.paths["/pet"]?.get.servers[0].url).to.equal("https://petstore3.swagger.com/api/v5");
90+
}
91+
catch (error) {
92+
console.error("\n\nError in non-relative servers at root but local file import test case:", error);
8893
throw error;
8994
}
9095
});

0 commit comments

Comments
 (0)