serverless-openapi-documenter 0.0.3 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -34
- package/package.json +11 -5
- package/src/definitionGenerator.js +60 -3
- package/src/openAPIGenerator.js +3 -2
- package/test/serverless 2/serverless.yml +6 -0
package/README.md
CHANGED
|
@@ -40,40 +40,51 @@ Options:
|
|
|
40
40
|
|
|
41
41
|
### OpenAPI Mapping
|
|
42
42
|
|
|
43
|
-
| OpenAPI field
|
|
44
|
-
|
|
45
|
-
| info.title
|
|
46
|
-
| info.description
|
|
47
|
-
| info.version
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
| path[path]
|
|
53
|
-
| path[path].
|
|
54
|
-
| path[path].
|
|
55
|
-
| path[path].[
|
|
56
|
-
| path[path].[
|
|
57
|
-
| path[path].[operation]
|
|
58
|
-
| path[path].[operation].
|
|
59
|
-
| path[path].[operation].
|
|
60
|
-
| path[path].[operation].
|
|
61
|
-
| path[path].[operation].
|
|
62
|
-
| path[path].[operation].
|
|
63
|
-
| path[path].[operation].
|
|
64
|
-
| path[path].[operation].
|
|
65
|
-
| path[path].[operation].
|
|
66
|
-
| path[path].[operation].
|
|
67
|
-
| path[path].[operation].parameters
|
|
68
|
-
| path[path].[operation].parameters.
|
|
69
|
-
| path[path].[operation].
|
|
70
|
-
| path[path].[operation].
|
|
71
|
-
| path[path].[operation].
|
|
72
|
-
| path[path].[operation].
|
|
73
|
-
| path[path].[operation].
|
|
74
|
-
| path[path].[operation].
|
|
75
|
-
| path[path].[operation].
|
|
76
|
-
| path[path].[operation].
|
|
43
|
+
| OpenAPI field | Serverless field |
|
|
44
|
+
|--------------------------|------------------------------------------------------------------------------------|
|
|
45
|
+
| info.title | custom.documentation.title OR service |
|
|
46
|
+
| info.description | custom.documentation.description OR blank string |
|
|
47
|
+
| info.version | custom.documentation.version OR random v4 uuid if not provided |
|
|
48
|
+
| externalDocs.description | custom.documentation.externalDocumentation.description |
|
|
49
|
+
| externalDocs.url | custom.documentation.externalDocumentation.url |
|
|
50
|
+
| servers[].description | custom.documentation.servers.description |
|
|
51
|
+
| servers[].url | custom.documentation.servers.url |
|
|
52
|
+
| path[path] | functions.functions.events.[http OR httpApi].path |
|
|
53
|
+
| path[path].summary | functions.functions.summary |
|
|
54
|
+
| path[path].description | functions.functions.description |
|
|
55
|
+
| path[path].servers[].description | functions.functions.servers.description |
|
|
56
|
+
| path[path].servers[].url | functions.functions.servers.url |
|
|
57
|
+
| path[path].[operation] | functions.functions.[http OR httpApi].method |
|
|
58
|
+
| path[path].[operation].summary | functions.functions.[http OR httpApi].documentation.summary |
|
|
59
|
+
| path[path].[operation].description | functions.functions.[http OR httpApi].documentation.description |
|
|
60
|
+
| path[path].[operation].operationId | functions.functions.[http OR httpApi].documentation.operationId OR functionName |
|
|
61
|
+
| path[path].[operation].deprecated | functions.functions.[http OR httpApi].documentation.deprecated |
|
|
62
|
+
| path[path].[operation].externalDocs.description | functions.functions.[http OR httpApi].documentation.externalDocumentation.description |
|
|
63
|
+
| path[path].[operation].externalDocs.url | functions.functions.[http OR httpApi].documentation.externalDocumentation.url |
|
|
64
|
+
| path[path].[operation].servers[].description | functions.functions.[http OR httpApi].documentation.servers.description |
|
|
65
|
+
| path[path].[operation].servers[].url | functions.functions.[http OR httpApi].documentation.servers.url |
|
|
66
|
+
| path[path].[operation].deprecated | functions.functions.[http OR httpApi].documentation.deprecated |
|
|
67
|
+
| path[path].[operation].parameters | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params |
|
|
68
|
+
| path[path].[operation].parameters.name | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.name |
|
|
69
|
+
| path[path].[operation].parameters.in | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params |
|
|
70
|
+
| path[path].[operation].parameters.description | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.description |
|
|
71
|
+
| path[path].[operation].parameters.required | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.required |
|
|
72
|
+
| path[path].[operation].parameters.deprecated | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.deprecated |
|
|
73
|
+
| path[path].[operation].parameters.allowEmptyValue | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.allowEmptyValue |
|
|
74
|
+
| path[path].[operation].parameters.style | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.style |
|
|
75
|
+
| path[path].[operation].parameters.explode | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.explode |
|
|
76
|
+
| path[path].[operation].parameters.allowReserved | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.allowReserved |
|
|
77
|
+
| path[path].[operation].parameters.schema | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.schema |
|
|
78
|
+
| path[path].[operation].parameters.example | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.example |
|
|
79
|
+
| path[path].[operation].parameters.examples | functions.functions.[http OR httpApi].documentation.[path|query|cookie|header]Params.examples |
|
|
80
|
+
| path[path].[operation].requestBody | functions.functions.[http OR httpApi].documentation.requestBody |
|
|
81
|
+
| path[path].[operation].requestBody.description | functions.functions.[http OR httpApi].documentation.requestBody.description |
|
|
82
|
+
| path[path].[operation].requestBody.required | functions.functions.[http OR httpApi].documentation.requestBody.required |
|
|
83
|
+
| path[path].[operation].requestBody.content | functions.functions.[http OR httpApi].documentation.requestModels[contentType].name Links to custom.documentation.models.name |
|
|
84
|
+
| path[path].[operation].responses | functions.functions.[http OR httpApi].documentation.methodResponses |
|
|
85
|
+
| path[path].[operation].requestBody.[statusCode] | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode] |
|
|
86
|
+
| path[path].[operation].requestBody.[statusCode].description | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode].responseBody.description |
|
|
87
|
+
| path[path].[operation].requestBody.[statusCode].content | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode].responseModels[contentType] Links to custom.documentation.models.name |
|
|
77
88
|
|
|
78
89
|
|
|
79
90
|
### Configuration
|
|
@@ -89,6 +100,12 @@ custom:
|
|
|
89
100
|
title: 'My API'
|
|
90
101
|
description: 'This is my API'
|
|
91
102
|
models: {}
|
|
103
|
+
externalDocumentation:
|
|
104
|
+
url: https://google.com
|
|
105
|
+
description: A link to google
|
|
106
|
+
servers:
|
|
107
|
+
url: https://example.com
|
|
108
|
+
description: The server
|
|
92
109
|
```
|
|
93
110
|
|
|
94
111
|
These configurations can be quite verbose; you can separate it out into it's own file, such as `serverless.doc.yml` as below:
|
|
@@ -178,6 +195,9 @@ functions:
|
|
|
178
195
|
documentation:
|
|
179
196
|
summary: "Create User"
|
|
180
197
|
description: "Creates a user and then sends a generated password email"
|
|
198
|
+
externalDocumentation:
|
|
199
|
+
url: https://bing.com
|
|
200
|
+
description: A link to bing
|
|
181
201
|
requestBody:
|
|
182
202
|
description: "A user information object"
|
|
183
203
|
requestModels:
|
package/package.json
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "serverless-openapi-documenter",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Generate OpenAPI v3 documentation and Postman Collections from your Serverless Config",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"keywords": [
|
|
6
|
+
"keywords": [
|
|
7
|
+
"serverless",
|
|
8
|
+
"serverless2",
|
|
9
|
+
"serverless3",
|
|
10
|
+
"openAPI",
|
|
11
|
+
"openAPIv3",
|
|
12
|
+
"openAPI3",
|
|
13
|
+
"PostmanCollections",
|
|
14
|
+
"Postman-Collections"
|
|
15
|
+
],
|
|
7
16
|
"scripts": {
|
|
8
17
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
18
|
},
|
|
@@ -18,9 +27,6 @@
|
|
|
18
27
|
"url": "https://github.com/JaredCE/serverless-openapi-documenter/issues"
|
|
19
28
|
},
|
|
20
29
|
"license": "MIT",
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"serverless": "^3.17.0"
|
|
23
|
-
},
|
|
24
30
|
"dependencies": {
|
|
25
31
|
"chalk": "^4.1.2",
|
|
26
32
|
"js-yaml": "^4.1.0",
|
|
@@ -6,7 +6,7 @@ const SchemaConvertor = require('json-schema-for-openapi')
|
|
|
6
6
|
|
|
7
7
|
class DefinitionGenerator {
|
|
8
8
|
constructor(serverless, options = {}) {
|
|
9
|
-
this.version = options.
|
|
9
|
+
this.version = serverless.processedInput.options.openApiVersion || '3.0.0'
|
|
10
10
|
|
|
11
11
|
this.serverless = serverless
|
|
12
12
|
this.httpKeys = {
|
|
@@ -29,6 +29,11 @@ class DefinitionGenerator {
|
|
|
29
29
|
parse() {
|
|
30
30
|
this.createInfo()
|
|
31
31
|
this.createPaths()
|
|
32
|
+
if (this.serverless.service.custom.documentation.servers) {
|
|
33
|
+
const servers = this.createServers(this.serverless.service.custom.documentation.servers)
|
|
34
|
+
Object.assign(this.openAPI, {servers: servers})
|
|
35
|
+
}
|
|
36
|
+
this.createExternalDocumentation()
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
createInfo() {
|
|
@@ -36,7 +41,7 @@ class DefinitionGenerator {
|
|
|
36
41
|
const documentation = this.serverless.service.custom.documentation;
|
|
37
42
|
|
|
38
43
|
const info = {
|
|
39
|
-
title: service.service,
|
|
44
|
+
title: documentation?.title || service.service,
|
|
40
45
|
description: documentation?.description || '',
|
|
41
46
|
version: documentation?.version || uuid(),
|
|
42
47
|
}
|
|
@@ -67,6 +72,11 @@ class DefinitionGenerator {
|
|
|
67
72
|
if (httpFunction.functionInfo?.description)
|
|
68
73
|
path.description = httpFunction.functionInfo.description
|
|
69
74
|
|
|
75
|
+
if (httpFunction.functionInfo?.servers) {
|
|
76
|
+
const servers = this.createServers(httpFunction.functionInfo.servers)
|
|
77
|
+
path.servers = servers
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
let slashPath = event.http.path
|
|
71
81
|
const pathStart = new RegExp(/^\//, 'g')
|
|
72
82
|
if (pathStart.test(slashPath) === false) {
|
|
@@ -80,6 +90,44 @@ class DefinitionGenerator {
|
|
|
80
90
|
Object.assign(this.openAPI, {paths})
|
|
81
91
|
}
|
|
82
92
|
|
|
93
|
+
createServers(servers) {
|
|
94
|
+
const serverDoc = servers
|
|
95
|
+
const newServers = []
|
|
96
|
+
|
|
97
|
+
if (Array.isArray(serverDoc)) {
|
|
98
|
+
for (const server of serverDoc) {
|
|
99
|
+
const obj = {
|
|
100
|
+
url: server.url,
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (server.description) {
|
|
104
|
+
obj.description = server.description
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
newServers.push(obj)
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
const obj = {
|
|
111
|
+
url: servers.url,
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (servers.description) {
|
|
115
|
+
obj.description = servers.description
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
newServers.push(obj)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return newServers
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
createExternalDocumentation() {
|
|
125
|
+
const documentation = this.serverless.service.custom.documentation
|
|
126
|
+
if (documentation.externalDocumentation) {
|
|
127
|
+
Object.assign(this.openAPI, {externalDocs: {...documentation.externalDocumentation}})
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
83
131
|
createOperationObject(method, documentation, name = uuid()) {
|
|
84
132
|
const obj = {
|
|
85
133
|
summary: documentation.summary || '',
|
|
@@ -109,8 +157,12 @@ class DefinitionGenerator {
|
|
|
109
157
|
obj.parameters = obj.parameters.concat(paramObject)
|
|
110
158
|
}
|
|
111
159
|
|
|
160
|
+
if (documentation.externalDocumentation) {
|
|
161
|
+
obj.externalDocs = documentation.externalDocumentation
|
|
162
|
+
}
|
|
163
|
+
|
|
112
164
|
if (Object.keys(documentation).includes('deprecated'))
|
|
113
|
-
obj
|
|
165
|
+
obj.deprecated = documentation.deprecated
|
|
114
166
|
|
|
115
167
|
if (documentation.requestBody)
|
|
116
168
|
obj.requestBody = this.createRequestBody(documentation)
|
|
@@ -118,6 +170,11 @@ class DefinitionGenerator {
|
|
|
118
170
|
if (documentation.methodResponses)
|
|
119
171
|
obj.responses = this.createResponses(documentation)
|
|
120
172
|
|
|
173
|
+
if (documentation.servers) {
|
|
174
|
+
const servers = this.createServers(documentation.servers)
|
|
175
|
+
obj.servers = servers
|
|
176
|
+
}
|
|
177
|
+
|
|
121
178
|
return {[method]: obj}
|
|
122
179
|
}
|
|
123
180
|
|
package/src/openAPIGenerator.js
CHANGED
|
@@ -70,7 +70,8 @@ class OpenAPIGenerator {
|
|
|
70
70
|
this.serverless.configSchemaHandler.defineFunctionProperties('aws', {
|
|
71
71
|
properties: {
|
|
72
72
|
// description: {type: 'string'},
|
|
73
|
-
summary: {type: 'string'}
|
|
73
|
+
summary: {type: 'string'},
|
|
74
|
+
servers: {anyOf: [{type:'object'}, {type:'array'}]},
|
|
74
75
|
}
|
|
75
76
|
})
|
|
76
77
|
}
|
|
@@ -126,7 +127,7 @@ class OpenAPIGenerator {
|
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
const postmanCollection = PostmanGenerator.convert(
|
|
129
|
-
{type: 'json', data: generator.openAPI},
|
|
130
|
+
{type: 'json', data: JSON.parse(JSON.stringify(generator.openAPI))},
|
|
130
131
|
{},
|
|
131
132
|
postmanGeneration
|
|
132
133
|
)
|
|
@@ -19,6 +19,9 @@ functions:
|
|
|
19
19
|
documentation:
|
|
20
20
|
summary: Create User
|
|
21
21
|
description: Creates a user and then sends a generated password email
|
|
22
|
+
externalDocumentation:
|
|
23
|
+
url: https://bing.com
|
|
24
|
+
description: A link to bing
|
|
22
25
|
requestBody:
|
|
23
26
|
description: A user information object
|
|
24
27
|
requestModels:
|
|
@@ -64,6 +67,9 @@ custom:
|
|
|
64
67
|
documentation:
|
|
65
68
|
description: This is a description of what this does
|
|
66
69
|
version: 1.0.0
|
|
70
|
+
externalDocumentation:
|
|
71
|
+
url: https://google.com
|
|
72
|
+
description: A link to google
|
|
67
73
|
models:
|
|
68
74
|
- name: ErrorResponse
|
|
69
75
|
description: This is an error
|