serverless-openapi-documenter 0.0.12 → 0.0.13

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
@@ -15,13 +15,13 @@ Originally based off of: https://github.com/temando/serverless-openapi-documenta
15
15
 
16
16
  ## Install
17
17
 
18
- This plugin works for Serverless 2.x and up.
18
+ This plugin works for Serverless 2.x and up and only supports node.js 14 and up.
19
19
 
20
20
  To add this plugin to your package.json:
21
21
 
22
22
  **Using npm:**
23
23
  ```bash
24
- npm install --save-dev serverless-openapi-documenter
24
+ npm install --save-dev serverless-openapi-documenter
25
25
  ```
26
26
 
27
27
  Next you need to add the plugin to the `plugins` section of your `serverless.yml` file.
@@ -112,7 +112,6 @@ custom:
112
112
  version: '1'
113
113
  title: 'My API'
114
114
  description: 'This is my API'
115
- models: {}
116
115
  externalDocumentation:
117
116
  url: https://google.com
118
117
  description: A link to google
@@ -125,8 +124,11 @@ custom:
125
124
  externalDocumentation:
126
125
  url: https://npmjs.com
127
126
  description: A link to npm
127
+ models: {}
128
128
  ```
129
129
 
130
+ Mostly everything here is optional. A version from a UUID will be generated for you if you don't specify one, title will be the name of your service if you don't specify one.
131
+
130
132
  These configurations can be quite verbose; you can separate it out into it's own file, such as `serverless.doc.yml` as below:
131
133
 
132
134
  ```yml
@@ -146,9 +148,10 @@ For more info on `serverless.yml` syntax, see their docs.
146
148
 
147
149
  #### Models
148
150
 
149
- Models contain additional information that you can use to define schemas for endpoints. You must define the *content type* for each schema that you provide in the models.
151
+ There are two ways to write the Models. Models contain additional information that you can use to define schemas for endpoints. You must define the *content type* for each schema that you provide in the models.
150
152
 
151
- The *required* directives for the models section are as follow:
153
+ The first way of writing the model is:
154
+ *required* directives for the models section are as follow:
152
155
 
153
156
  * `name`: the name of the schema
154
157
  * `description`: a description of the schema
@@ -180,6 +183,40 @@ custom:
180
183
  type: "string"
181
184
  ```
182
185
 
186
+ The Second way of writing the models:
187
+
188
+ * `name`: the name of the schema
189
+ * `description`: a description of the schema
190
+ * `content`: an Object made up of the contentType and the schema, as shown below
191
+
192
+ ```yml
193
+ custom:
194
+ documentation:
195
+ models:
196
+ - name: "ErrorResponse"
197
+ description: "This is an error"
198
+ content:
199
+ application/json:
200
+ schema: ${file(models/ErrorResponse.json)}
201
+ - name: "PutDocumentResponse"
202
+ description: "PUT Document response model (external reference example)"
203
+ content:
204
+ application/json:
205
+ schema: ${file(models/PutDocumentResponse.json)}
206
+ - name: "PutDocumentRequest"
207
+ description: "PUT Document request model (inline example)"
208
+ content:
209
+ application/json:
210
+ schema:
211
+ $schema: "http://json-schema.org/draft-04/schema#"
212
+ properties:
213
+ SomeObject:
214
+ type: "object"
215
+ properties:
216
+ SomeAttribute:
217
+ type: "string"
218
+ ```
219
+
183
220
  #### Functions
184
221
 
185
222
  To define the documentation for a given function event, you need to create a `documentation` attribute for your http event in your `serverless.yml` file.
@@ -206,11 +243,12 @@ The `documentation` section of the event configuration can contain the following
206
243
  ```yml
207
244
  functions:
208
245
  createUser:
209
- handler: "handler.create"
246
+ handler: handler.create
210
247
  events:
211
248
  - http:
212
- path: "create"
213
- method: "post"
249
+ path: create
250
+ method: post
251
+ summary:
214
252
  documentation:
215
253
  summary: "Create User"
216
254
  description: "Creates a user and then sends a generated password email"
@@ -375,7 +413,7 @@ Please view the example [serverless.yml](test/serverless\ 2/serverless.yml).
375
413
 
376
414
  ## Notes on schemas
377
415
 
378
- Schemas can be either: inline, in file or externally hosted. If they're inline or in file, the plugin will attempt to normalise the schema to [OpenAPI 3.0.X specification](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#schemaObject).
416
+ Schemas can be either: inline, in file or externally hosted. If they're inline or in file, the plugin will attempt to normalise the schema to [OpenAPI 3.0.X specification](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#schemaObject).
379
417
 
380
418
  If they exist as an external reference, for instance:
381
419
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serverless-openapi-documenter",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "description": "Generate OpenAPI v3 documentation and Postman Collections from your Serverless Config",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -33,7 +33,7 @@ class DefinitionGenerator {
33
33
  } catch (err) {
34
34
  this.refParserOptions = {}
35
35
  }
36
-
36
+
37
37
  }
38
38
 
39
39
  async parse() {
@@ -42,7 +42,7 @@ class DefinitionGenerator {
42
42
  .catch(err => {
43
43
  throw err
44
44
  })
45
-
45
+
46
46
  if (this.serverless.service.custom.documentation.servers) {
47
47
  const servers = this.createServers(this.serverless.service.custom.documentation.servers)
48
48
  Object.assign(this.openAPI, {servers: servers})
@@ -73,11 +73,10 @@ class DefinitionGenerator {
73
73
  async createPaths() {
74
74
  const paths = {}
75
75
  const httpFunctions = this.getHTTPFunctions()
76
-
77
76
  for (const httpFunction of httpFunctions) {
78
77
  for (const event of httpFunction.event) {
79
78
  if (event?.http?.documentation || event?.httpApi?.documentation) {
80
- const documentation = event.http.documentation || event.httpApi.documentation
79
+ const documentation = event?.http?.documentation || event?.httpApi?.documentation
81
80
 
82
81
  let opId
83
82
  if (this.operationIds.includes(httpFunction.functionInfo.name) === false) {
@@ -87,11 +86,11 @@ class DefinitionGenerator {
87
86
  opId = `${httpFunction.functionInfo.name}-${uuid()}`
88
87
  }
89
88
 
90
- const path = await this.createOperationObject(event.http.method || event.httpApi.method, documentation, opId)
89
+ const path = await this.createOperationObject(event?.http?.method || event?.httpApi?.method, documentation, opId)
91
90
  .catch(err => {
92
91
  throw err
93
92
  })
94
-
93
+
95
94
  if (httpFunction.functionInfo?.summary)
96
95
  path.summary = httpFunction.functionInfo.summary
97
96
 
@@ -103,10 +102,10 @@ class DefinitionGenerator {
103
102
  path.servers = servers
104
103
  }
105
104
 
106
- let slashPath = event.http.path
105
+ let slashPath = event?.http?.path || event.httpApi?.path
107
106
  const pathStart = new RegExp(/^\//, 'g')
108
107
  if (pathStart.test(slashPath) === false) {
109
- slashPath = `/${event.http.path}`
108
+ slashPath = `/${event?.http?.path||event.httpApi?.path}`
110
109
  }
111
110
 
112
111
  Object.assign(paths, {[slashPath]: path})
@@ -152,7 +151,7 @@ class DefinitionGenerator {
152
151
  // const documentation = this.serverless.service.custom.documentation
153
152
  // if (documentation.externalDocumentation) {
154
153
  // // Object.assign(this.openAPI, {externalDocs: {...documentation.externalDocumentation}})
155
- // return
154
+ // return
156
155
  // }
157
156
  }
158
157
 
@@ -240,7 +239,7 @@ class DefinitionGenerator {
240
239
  obj.servers = servers
241
240
  }
242
241
 
243
- return {[method]: obj}
242
+ return {[method.toLowerCase()]: obj}
244
243
  }
245
244
 
246
245
  async createResponses(documentation) {
@@ -292,14 +291,19 @@ class DefinitionGenerator {
292
291
  if (mediaTypeDocumentation.examples)
293
292
  obj.examples = this.createExamples(mediaTypeDocumentation.examples)
294
293
 
295
- if (mediaTypeDocumentation.content[contentKey].schema) {
296
- const schemaRef = await this.schemaCreator(mediaTypeDocumentation.content[contentKey].schema, mediaTypeDocumentation.name)
297
- .catch(err => {
298
- throw err
299
- })
300
- obj.schema = {
301
- $ref: schemaRef
302
- }
294
+ let schema
295
+ if (mediaTypeDocumentation?.content) {
296
+ schema = mediaTypeDocumentation.content[contentKey].schema
297
+ } else if (mediaTypeDocumentation?.contentType && mediaTypeDocumentation.schema) {
298
+ schema = mediaTypeDocumentation.schema
299
+ }
300
+
301
+ const schemaRef = await this.schemaCreator(schema, mediaTypeDocumentation.name)
302
+ .catch(err => {
303
+ throw err
304
+ })
305
+ obj.schema = {
306
+ $ref: schemaRef
303
307
  }
304
308
 
305
309
  Object.assign(mediaTypeObj, {[contentKey]: obj})
@@ -19,7 +19,7 @@ functions:
19
19
  documentation:
20
20
  summary: Create User
21
21
  description: Creates a user and then sends a generated password email
22
- tags:
22
+ tags:
23
23
  - jesus
24
24
  externalDocumentation:
25
25
  url: https://bing.com
@@ -64,12 +64,28 @@ functions:
64
64
  - http:
65
65
  path: delete
66
66
  method: delete
67
-
67
+ patchUser:
68
+ handler: handler.patch
69
+ events:
70
+ - httpApi:
71
+ path: /patch/
72
+ method: PATCH
73
+ documentation:
74
+ summary: Patch a User
75
+ description: Patch details about the user
76
+ tags:
77
+ - patching
78
+ methodResponses:
79
+ - statusCode: 200
80
+ responseBody:
81
+ description: A user object along with generated API Keys
82
+ responseModels:
83
+ application/json: PutDocumentResponse
68
84
  custom:
69
85
  documentation:
70
86
  description: This is a description of what this does
71
87
  version: 1.0.0
72
- tags:
88
+ tags:
73
89
  - name: jesus
74
90
  description: jesus was a man
75
91
  externalDocumentation: