Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ Options:
| tags[].externalDocs.url | `custom.documentation.tags.externalDocumentation.url` |
| tags[].externalDocs.description | `custom.documentation.tags.externalDocumentation.description` |
| tags[].externalDocs.x- | `custom.documentation.tags.externalDocumentation.x-` if extended specifications provided |
| basePath | `custom.documentation.basePath`Specifies the base path to prepend to all Lambda HTTP function paths in the generated OpenAPI specification |
| paths | `custom.documentation.paths` OpenAPI paths that are not backed by Lambda functions |
| path[path] | functions.functions.events.[http OR httpApi].path |
| path[path].servers[].description | functions.functions.servers.description |
Expand Down
26 changes: 16 additions & 10 deletions src/definitionGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,26 +281,32 @@ class DefinitionGenerator {
const paths = this.serverless.service.custom.documentation.paths;

if (paths) {
const basePath = this.getBasePath();

if (basePath) {
// check is paths's keys are not starting with `basePath` prefix and if set append it
for (const key of Object.keys(paths)) {
if (!key.startsWith(`/${basePath}`)) {
paths[`/${basePath}${key}`] = paths[key];
delete paths[key];
}
}
}

const origPaths = this.openAPI.paths || {};

Object.assign(this.openAPI, { paths: { ...origPaths, ...paths } });
}
}

/**
* @description Retrieves the basePath value if the domain manager plugin is used, allowing the server URL to be just the plain domain. The `basePath` will be prepended to each Lambda HTTP path.
* @description Retrieves the basePath value if set, allowing the server URL to be just the plain domain. The `basePath` will be prepended to each Lambda HTTP path. If `basePath` starts with a slash (/) returns the basePath without the leading slash.
* @returns {string}
*/
getBasePath() {
const plugins = this.serverless.service.plugins || [];

let basePath = "";

if (plugins.includes("serverless-domain-manager")) {
basePath = this.serverless.service.custom.basePath || "";
}

return basePath;
const basePath =
this.serverless.service.custom.documentation.basePath || "";
return basePath.replace(/^\//, "");
}

createServers(servers) {
Expand Down
56 changes: 40 additions & 16 deletions test/helpers/serverless.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,43 @@
'use strict'
"use strict";

module.exports = {
processedInput: {
options: {
openApiVersion: '3.0.1'
}
processedInput: {
options: {
openApiVersion: "3.0.1",
},
service: {
service: 'myAPI',
custom: {
documentation: {
title: 'My new API',
description: 'This API does things',
version: '0.0.1'
}
}
}
}
},
service: {
service: "myAPI",
custom: {
documentation: {
title: "My new API",
description: "This API does things",
version: "0.0.1",
basePath: "v1",
paths: {
"/test/path": {
post: {
tags: ["Ttest Api"],
summary: "Test Api",
parameters: [
{
in: "path",
name: "id",
required: true,
schema: {
type: "string",
},
},
],
responses: {
204: {
description: "No content",
},
},
},
},
},
},
},
},
};
38 changes: 38 additions & 0 deletions test/unit/definitionGenerator.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,44 @@ describe("DefinitionGenerator", () => {
expect(expected.version).to.be.equal("3.0.0");
});

it("should use the basePath when supplied", async function () {
const serverlessWithOpenAPIVersion = structuredClone(mockServerless);
const expected = new DefinitionGenerator(
serverlessWithOpenAPIVersion,
logger
);
const serverlessWithOpenAPIVersion2 = structuredClone(mockServerless);
delete serverlessWithOpenAPIVersion2.service.custom.documentation
.basePath;
const expectedWithoutBasePath = new DefinitionGenerator(
serverlessWithOpenAPIVersion2,
logger
);

expected.mergeExistingPaths();
expectedWithoutBasePath.mergeExistingPaths();

expect(expected.getBasePath()).to.be.equal(
serverlessWithOpenAPIVersion.service.custom.documentation.basePath
);
expect(
Object.keys(expected.openAPI.paths).every((key) =>
key.startsWith(`/${expected.getBasePath()}`)
)
).to.be.equal(true);

expect(expectedWithoutBasePath.getBasePath()).to.be.equal("");
expect(
Object.keys(expectedWithoutBasePath.openAPI.paths).every((key, idx) =>
key.startsWith(
Object.keys(
serverlessWithOpenAPIVersion2.service.custom.documentation.paths
)[idx]
)
)
).to.be.equal(true);
});

it("should respect the version of openAPI when passed in", function () {
const serverlessWithOpenAPIVersion = structuredClone(mockServerless);
serverlessWithOpenAPIVersion.processedInput.options.openApiVersion =
Expand Down
Loading