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 CHANGED
@@ -40,40 +40,51 @@ Options:
40
40
 
41
41
  ### OpenAPI Mapping
42
42
 
43
- | OpenAPI field | Serverless field |
44
- |--------------------|------------------------------------------------------------------------------------|
45
- | info.title | service |
46
- | info.description | custom.documentation.description || blank string |
47
- | info.version | custom.documentation.version || random v4 uuid if not provided |
48
- | path[path] | functions.functions.events.[http||httpApi].path |
49
- | path[path].summary | functions.functions.summary |
50
- | path[path].description | functions.functions.description |
51
- | path[path].[operation] | functions.functions.[http||httpApi].method |
52
- | path[path].[operation].summary | functions.functions.[http||httpApi].documentation.summary |
53
- | path[path].[operation].description | functions.functions.[http||httpApi].documentation.description |
54
- | path[path].[operation].operationId | functions.functions.[http||httpApi].documentation.operationId || functionName |
55
- | path[path].[operation].deprecated | functions.functions.[http||httpApi].documentation.deprecated |
56
- | path[path].[operation].parameters | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params |
57
- | path[path].[operation].parameters.name | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.name |
58
- | path[path].[operation].parameters.in | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params |
59
- | path[path].[operation].parameters.description | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.description |
60
- | path[path].[operation].parameters.required | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.required |
61
- | path[path].[operation].parameters.deprecated | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.deprecated |
62
- | path[path].[operation].parameters.allowEmptyValue | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.allowEmptyValue |
63
- | path[path].[operation].parameters.style | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.style |
64
- | path[path].[operation].parameters.explode | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.explode |
65
- | path[path].[operation].parameters.allowReserved | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.allowReserved |
66
- | path[path].[operation].parameters.schema | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.schema |
67
- | path[path].[operation].parameters.example | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.example |
68
- | path[path].[operation].parameters.examples | functions.functions.[http||httpApi].documentation.[path|query|cookie|header]Params.examples |
69
- | path[path].[operation].requestBody | functions.functions.[http||httpApi].documentation.requestBody |
70
- | path[path].[operation].requestBody.description | functions.functions.[http||httpApi].documentation.requestBody.description |
71
- | path[path].[operation].requestBody.required | functions.functions.[http||httpApi].documentation.requestBody.required |
72
- | path[path].[operation].requestBody.content | functions.functions.[http||httpApi].documentation.requestModels[contentType].name Links to custom.documentation.models.name |
73
- | path[path].[operation].responses | functions.functions.[http||httpApi].documentation.methodResponses |
74
- | path[path].[operation].requestBody.[statusCode] | functions.functions.[http||httpApi].documentation.methodResponses[statusCode] |
75
- | path[path].[operation].requestBody.[statusCode].description | functions.functions.[http||httpApi].documentation.methodResponses[statusCode].responseBody.description |
76
- | path[path].[operation].requestBody.[statusCode].content | functions.functions.[http||httpApi].documentation.methodResponses[statusCode].responseModels[contentType] Links to custom.documentation.models.name |
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",
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": ["serverless", "serverless2", "serverless3", "openAPI", "openAPIv3", "openAPI3", "PostmanCollections", "Postman-Collections"],
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.v || '3.0.0'
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[method].deprecated = documentation.deprecated
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
 
@@ -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