serverless-openapi-documenter 0.0.12 → 0.0.16

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.
@@ -0,0 +1,31 @@
1
+ # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2
+ # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3
+
4
+ name: Node.js CI
5
+
6
+ on:
7
+ push:
8
+ branches: [ "main" ]
9
+ pull_request:
10
+ branches: [ "main" ]
11
+
12
+ jobs:
13
+ build:
14
+
15
+ runs-on: ubuntu-latest
16
+
17
+ strategy:
18
+ matrix:
19
+ node-version: [14.x, 16.x]
20
+ # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21
+
22
+ steps:
23
+ - uses: actions/checkout@v3
24
+ - name: Use Node.js ${{ matrix.node-version }}
25
+ uses: actions/setup-node@v3
26
+ with:
27
+ node-version: ${{ matrix.node-version }}
28
+ cache: 'npm'
29
+ - run: npm ci
30
+ - run: npm run build --if-present
31
+ - run: npm test
package/README.md CHANGED
@@ -9,19 +9,21 @@
9
9
  </a>
10
10
  </p>
11
11
 
12
+ ![node.js tests](https://github.com/JaredCE/serverless-openapi-documenter/actions/workflows/node.js.yml/badge.svg)
13
+
12
14
  This will generate an OpenAPI V3 (up to v3.0.3) file for you from your serverless file. It can optionally generate a Postman Collection V2 from the OpenAPI file for you too.
13
15
 
14
16
  Originally based off of: https://github.com/temando/serverless-openapi-documentation
15
17
 
16
18
  ## Install
17
19
 
18
- This plugin works for Serverless 2.x and up.
20
+ This plugin works for Serverless 2.x and up and only supports node.js 14 and up.
19
21
 
20
22
  To add this plugin to your package.json:
21
23
 
22
24
  **Using npm:**
23
25
  ```bash
24
- npm install --save-dev serverless-openapi-documenter
26
+ npm install --save-dev serverless-openapi-documenter
25
27
  ```
26
28
 
27
29
  Next you need to add the plugin to the `plugins` section of your `serverless.yml` file.
@@ -112,7 +114,6 @@ custom:
112
114
  version: '1'
113
115
  title: 'My API'
114
116
  description: 'This is my API'
115
- models: {}
116
117
  externalDocumentation:
117
118
  url: https://google.com
118
119
  description: A link to google
@@ -125,8 +126,11 @@ custom:
125
126
  externalDocumentation:
126
127
  url: https://npmjs.com
127
128
  description: A link to npm
129
+ models: {}
128
130
  ```
129
131
 
132
+ 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.
133
+
130
134
  These configurations can be quite verbose; you can separate it out into it's own file, such as `serverless.doc.yml` as below:
131
135
 
132
136
  ```yml
@@ -146,9 +150,10 @@ For more info on `serverless.yml` syntax, see their docs.
146
150
 
147
151
  #### Models
148
152
 
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.
153
+ 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
154
 
151
- The *required* directives for the models section are as follow:
155
+ The first way of writing the model is:
156
+ *required* directives for the models section are as follow:
152
157
 
153
158
  * `name`: the name of the schema
154
159
  * `description`: a description of the schema
@@ -180,6 +185,40 @@ custom:
180
185
  type: "string"
181
186
  ```
182
187
 
188
+ The Second way of writing the models:
189
+
190
+ * `name`: the name of the schema
191
+ * `description`: a description of the schema
192
+ * `content`: an Object made up of the contentType and the schema, as shown below
193
+
194
+ ```yml
195
+ custom:
196
+ documentation:
197
+ models:
198
+ - name: "ErrorResponse"
199
+ description: "This is an error"
200
+ content:
201
+ application/json:
202
+ schema: ${file(models/ErrorResponse.json)}
203
+ - name: "PutDocumentResponse"
204
+ description: "PUT Document response model (external reference example)"
205
+ content:
206
+ application/json:
207
+ schema: ${file(models/PutDocumentResponse.json)}
208
+ - name: "PutDocumentRequest"
209
+ description: "PUT Document request model (inline example)"
210
+ content:
211
+ application/json:
212
+ schema:
213
+ $schema: "http://json-schema.org/draft-04/schema#"
214
+ properties:
215
+ SomeObject:
216
+ type: "object"
217
+ properties:
218
+ SomeAttribute:
219
+ type: "string"
220
+ ```
221
+
183
222
  #### Functions
184
223
 
185
224
  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 +245,12 @@ The `documentation` section of the event configuration can contain the following
206
245
  ```yml
207
246
  functions:
208
247
  createUser:
209
- handler: "handler.create"
248
+ handler: handler.create
210
249
  events:
211
250
  - http:
212
- path: "create"
213
- method: "post"
251
+ path: create
252
+ method: post
253
+ summary:
214
254
  documentation:
215
255
  summary: "Create User"
216
256
  description: "Creates a user and then sends a generated password email"
@@ -375,7 +415,7 @@ Please view the example [serverless.yml](test/serverless\ 2/serverless.yml).
375
415
 
376
416
  ## Notes on schemas
377
417
 
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).
418
+ 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
419
 
380
420
  If they exist as an external reference, for instance:
381
421
 
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.16",
4
4
  "description": "Generate OpenAPI v3 documentation and Postman Collections from your Serverless Config",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -14,7 +14,7 @@
14
14
  "Postman-Collections"
15
15
  ],
16
16
  "scripts": {
17
- "test": "echo \"Error: no test specified\" && exit 1"
17
+ "test": "mocha --config './test/.mocharc.js'"
18
18
  },
19
19
  "author": {
20
20
  "name": "Jared Evans"
@@ -39,5 +39,10 @@
39
39
  },
40
40
  "engines": {
41
41
  "node": ">=14"
42
+ },
43
+ "devDependencies": {
44
+ "chai": "^4.3.6",
45
+ "mocha": "^10.0.0",
46
+ "sinon": "^14.0.0"
42
47
  }
43
48
  }
@@ -9,7 +9,7 @@ const $RefParser = require("@apidevtools/json-schema-ref-parser");
9
9
 
10
10
  class DefinitionGenerator {
11
11
  constructor(serverless, options = {}) {
12
- this.version = serverless.processedInput.options.openApiVersion || '3.0.0'
12
+ this.version = serverless?.processedInput?.options?.openApiVersion || '3.0.0'
13
13
 
14
14
  this.serverless = serverless
15
15
  this.httpKeys = {
@@ -27,13 +27,14 @@ class DefinitionGenerator {
27
27
  }
28
28
 
29
29
  this.operationIds = []
30
+ this.schemaIDs = []
30
31
 
31
32
  try {
32
33
  this.refParserOptions = require(path.resolve('options', 'ref-parser.js'))
33
34
  } catch (err) {
34
35
  this.refParserOptions = {}
35
36
  }
36
-
37
+
37
38
  }
38
39
 
39
40
  async parse() {
@@ -42,7 +43,7 @@ class DefinitionGenerator {
42
43
  .catch(err => {
43
44
  throw err
44
45
  })
45
-
46
+
46
47
  if (this.serverless.service.custom.documentation.servers) {
47
48
  const servers = this.createServers(this.serverless.service.custom.documentation.servers)
48
49
  Object.assign(this.openAPI, {servers: servers})
@@ -73,11 +74,10 @@ class DefinitionGenerator {
73
74
  async createPaths() {
74
75
  const paths = {}
75
76
  const httpFunctions = this.getHTTPFunctions()
76
-
77
77
  for (const httpFunction of httpFunctions) {
78
78
  for (const event of httpFunction.event) {
79
79
  if (event?.http?.documentation || event?.httpApi?.documentation) {
80
- const documentation = event.http.documentation || event.httpApi.documentation
80
+ const documentation = event?.http?.documentation || event?.httpApi?.documentation
81
81
 
82
82
  let opId
83
83
  if (this.operationIds.includes(httpFunction.functionInfo.name) === false) {
@@ -87,11 +87,11 @@ class DefinitionGenerator {
87
87
  opId = `${httpFunction.functionInfo.name}-${uuid()}`
88
88
  }
89
89
 
90
- const path = await this.createOperationObject(event.http.method || event.httpApi.method, documentation, opId)
90
+ const path = await this.createOperationObject(event?.http?.method || event?.httpApi?.method, documentation, opId)
91
91
  .catch(err => {
92
92
  throw err
93
93
  })
94
-
94
+
95
95
  if (httpFunction.functionInfo?.summary)
96
96
  path.summary = httpFunction.functionInfo.summary
97
97
 
@@ -103,10 +103,10 @@ class DefinitionGenerator {
103
103
  path.servers = servers
104
104
  }
105
105
 
106
- let slashPath = event.http.path
106
+ let slashPath = event?.http?.path || event.httpApi?.path
107
107
  const pathStart = new RegExp(/^\//, 'g')
108
108
  if (pathStart.test(slashPath) === false) {
109
- slashPath = `/${event.http.path}`
109
+ slashPath = `/${event?.http?.path||event.httpApi?.path}`
110
110
  }
111
111
 
112
112
  Object.assign(paths, {[slashPath]: path})
@@ -152,7 +152,7 @@ class DefinitionGenerator {
152
152
  // const documentation = this.serverless.service.custom.documentation
153
153
  // if (documentation.externalDocumentation) {
154
154
  // // Object.assign(this.openAPI, {externalDocs: {...documentation.externalDocumentation}})
155
- // return
155
+ // return
156
156
  // }
157
157
  }
158
158
 
@@ -240,7 +240,7 @@ class DefinitionGenerator {
240
240
  obj.servers = servers
241
241
  }
242
242
 
243
- return {[method]: obj}
243
+ return {[method.toLowerCase()]: obj}
244
244
  }
245
245
 
246
246
  async createResponses(documentation) {
@@ -292,14 +292,19 @@ class DefinitionGenerator {
292
292
  if (mediaTypeDocumentation.examples)
293
293
  obj.examples = this.createExamples(mediaTypeDocumentation.examples)
294
294
 
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
- }
295
+ let schema
296
+ if (mediaTypeDocumentation?.content) {
297
+ schema = mediaTypeDocumentation.content[contentKey].schema
298
+ } else if (mediaTypeDocumentation?.contentType && mediaTypeDocumentation.schema) {
299
+ schema = mediaTypeDocumentation.schema
300
+ }
301
+
302
+ const schemaRef = await this.schemaCreator(schema, mediaTypeDocumentation.name)
303
+ .catch(err => {
304
+ throw err
305
+ })
306
+ obj.schema = {
307
+ $ref: schemaRef
303
308
  }
304
309
 
305
310
  Object.assign(mediaTypeObj, {[contentKey]: obj})
@@ -381,14 +386,33 @@ class DefinitionGenerator {
381
386
 
382
387
  if (typeof schema !== 'string' && Object.keys(schema).length > 0) {
383
388
  const convertedSchema = SchemaConvertor.convert(schema)
389
+
390
+ let schemaName = name
391
+ if (this.schemaIDs.includes(schemaName))
392
+ schemaName = `${name}-${uuid()}`
393
+
394
+ this.schemaIDs.push(schemaName)
395
+
384
396
  for (const key of Object.keys(convertedSchema.schemas)) {
385
397
  if (key === 'main' || key.split('-')[0] === 'main') {
386
- const ref = `#/components/schemas/${name}`
398
+ let ref = `#/components/schemas/`
399
+
400
+ if (this.openAPI?.components?.schemas?.[name]) {
401
+ if (JSON.stringify(convertedSchema.schemas[key]) === JSON.stringify(this.openAPI.components.schemas[name])) {
402
+ return `${ref}${name}`
403
+ }
404
+ }
387
405
 
388
- addToComponents(convertedSchema.schemas[key], name)
389
- return ref
406
+ addToComponents(convertedSchema.schemas[key], schemaName)
407
+ return `${ref}${schemaName}`
390
408
  } else {
391
- addToComponents(convertedSchema.schemas[key], key)
409
+ if (this.openAPI?.components?.schemas?.[key]) {
410
+ if (JSON.stringify(convertedSchema.schemas[key]) !== JSON.stringify(this.openAPI.components.schemas[key])) {
411
+ addToComponents(convertedSchema.schemas[key], key)
412
+ }
413
+ } else {
414
+ addToComponents(convertedSchema.schemas[key], key)
415
+ }
392
416
  }
393
417
  }
394
418
  } else {
@@ -54,7 +54,6 @@ class OpenAPIGenerator {
54
54
  }
55
55
 
56
56
  this.hooks = {
57
- // 'before:deploy': this.beforeDeploy.bind(this),
58
57
  'openapi:generate:serverless': this.generate.bind(this),
59
58
  };
60
59
 
@@ -76,17 +75,23 @@ class OpenAPIGenerator {
76
75
 
77
76
  this.serverless.configSchemaHandler.defineFunctionProperties('aws', {
78
77
  properties: {
79
- // description: {type: 'string'},
80
78
  summary: {type: 'string'},
81
79
  servers: {anyOf: [{type:'object'}, {type:'array'}]},
82
80
  }
83
81
  })
84
82
  }
85
83
 
86
- log(type = this.defaultLog, ...str) {
84
+ log(type = this.defaultLog, str) {
87
85
  switch(this.serverless.version[0]) {
88
86
  case '2':
89
- this.serverless.cli.log(str)
87
+ let colouredString = str
88
+ if (type === 'error') {
89
+ colouredString = chalk.bold.red(`✖ ${str}`)
90
+ } else if (type === 'success') {
91
+ colouredString = chalk.bold.green(`✓ ${str}`)
92
+ }
93
+
94
+ this.serverless.cli.log(colouredString)
90
95
  break
91
96
 
92
97
  case '3':
@@ -106,32 +111,32 @@ class OpenAPIGenerator {
106
111
 
107
112
  await generator.parse()
108
113
  .catch(err => {
109
- this.log('error', chalk.bold.red(`ERROR: An error was thrown generating the OpenAPI v3 documentation`))
114
+ this.log('error', `ERROR: An error was thrown generating the OpenAPI v3 documentation`)
110
115
  throw new this.serverless.classes.Error(err)
111
116
  })
112
117
 
113
118
  const valid = await generator.validate()
114
119
  .catch(err => {
115
- this.log('error', chalk.bold.red(`ERROR: An error was thrown validating the OpenAPI v3 documentation`))
120
+ this.log('error', `ERROR: An error was thrown validating the OpenAPI v3 documentation`)
116
121
  throw new this.serverless.classes.Error(err)
117
122
  })
118
123
 
119
124
  if (valid)
120
- this.log(this.defaultLog, chalk.bold.green('OpenAPI v3 Documentation Successfully Generated'))
125
+ this.log('success', 'OpenAPI v3 Documentation Successfully Generated')
121
126
 
122
127
  if (config.postmanCollection) {
123
128
  const postmanGeneration = (err, result) => {
124
129
  if (err) {
125
- this.log('error', chalk.bold.red(`ERROR: An error was thrown when generating the postman collection`))
130
+ this.log('error', `ERROR: An error was thrown when generating the postman collection`)
126
131
  throw new this.serverless.classes.Error(err)
127
132
  }
128
133
 
129
- this.log(this.defaultLog, chalk.bold.green('postman collection v2 Documentation Successfully Generated'))
134
+ this.log('success', 'postman collection v2 Documentation Successfully Generated')
130
135
  try {
131
136
  fs.writeFileSync(config.postmanCollection, JSON.stringify(result.output[0].data))
132
- this.log(this.defaultLog, chalk.bold.green('postman collection v2 Documentation Successfully Written'))
137
+ this.log('success', 'postman collection v2 Documentation Successfully Written')
133
138
  } catch (err) {
134
- this.log('error', chalk.bold.red(`ERROR: An error was thrown whilst writing the postman collection`))
139
+ this.log('error', `ERROR: An error was thrown whilst writing the postman collection`)
135
140
  throw new this.serverless.classes.Error(err)
136
141
  }
137
142
  }
@@ -155,9 +160,9 @@ class OpenAPIGenerator {
155
160
  }
156
161
  try {
157
162
  fs.writeFileSync(config.file, output);
158
- this.log(this.defaultLog, chalk.bold.green('OpenAPI v3 Documentation Successfully Written'))
163
+ this.log('success', 'OpenAPI v3 Documentation Successfully Written')
159
164
  } catch (err) {
160
- this.log('error', chalk.bold.red(`ERROR: An error was thrown whilst writing the openAPI Documentation`))
165
+ this.log('error', `ERROR: An error was thrown whilst writing the openAPI Documentation`)
161
166
  throw new this.serverless.classes.Error(err)
162
167
  }
163
168
  }
@@ -177,7 +182,8 @@ class OpenAPIGenerator {
177
182
  config.postmanCollection = this.serverless.processedInput.options.postmanCollection || null
178
183
 
179
184
  if (['yaml', 'json'].indexOf(config.format.toLowerCase()) < 0) {
180
- throw new Error('Invalid Output Format Specified - must be one of "yaml" or "json"');
185
+ // throw new Error('Invalid Output Format Specified - must be one of "yaml" or "json"');
186
+ throw new this.serverless.classes.Error('Invalid Output Format Specified - must be one of "yaml" or "json"')
181
187
  }
182
188
 
183
189
  config.file = this.serverless.processedInput.options.output ||
@@ -185,12 +191,12 @@ class OpenAPIGenerator {
185
191
 
186
192
  this.log(
187
193
  this.defaultLog,
188
- `${chalk.bold.green('[OPTIONS]')}`,
189
- ` openApiVersion: "${chalk.bold.red(String(config.openApiVersion))}"`,
190
- ` format: "${chalk.bold.red(config.format)}"`,
191
- ` output file: "${chalk.bold.red(config.file)}"`,
192
- ` indentation: "${chalk.bold.red(String(config.indent))}"`,
193
- ` ${config.postmanCollection ? `postman collection: ${chalk.bold.red(config.postmanCollection)}`: `\n\n`}`
194
+ `${chalk.bold.green('[OPTIONS]')}
195
+ openApiVersion: "${chalk.bold.green(String(config.openApiVersion))}"
196
+ format: "${chalk.bold.green(config.format)}"
197
+ output file: "${chalk.bold.green(config.file)}"
198
+ indentation: "${chalk.bold.green(String(config.indent))}"
199
+ ${config.postmanCollection ? `postman collection: ${chalk.bold.green(config.postmanCollection)}`: `\n\n`}`
194
200
  )
195
201
 
196
202
  return config
@@ -0,0 +1,9 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ recursive: true,
5
+ reporter: 'spec',
6
+ spec: 'test/unit/*.spec.js',
7
+ watch: false,
8
+ 'watch-files': ['src/**/*.js', 'test/**/*.spec.js'],
9
+ }
@@ -0,0 +1,5 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ continueOnError: true, // Don't throw on the first error
5
+ }
@@ -0,0 +1,19 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ processedInput: {
5
+ options: {
6
+ openApiVersion: '3.0.1'
7
+ }
8
+ },
9
+ service: {
10
+ service: 'myAPI',
11
+ custom: {
12
+ documentation: {
13
+ title: 'My new API',
14
+ description: 'This API does things',
15
+ version: '0.0.1'
16
+ }
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,91 @@
1
+ {
2
+ "$comment": "JSON Schema for CSR Framework",
3
+ "$schema": "http://json-schema.org/draft-04/schema",
4
+ "definitions": {
5
+ "log": {
6
+ "type": "object",
7
+ "title": "Logger options",
8
+ "properties": {
9
+ "channel": {
10
+ "type": "string",
11
+ "default": "console"
12
+ },
13
+ "path": {
14
+ "type": "string",
15
+ "default": "../src/logs"
16
+ },
17
+ "template": {
18
+ "type": "object",
19
+ "properties": {
20
+ "message": {
21
+ "type": "string"
22
+ },
23
+ "file": {
24
+ "type": "string"
25
+ },
26
+ "dir": {
27
+ "type": "string"
28
+ }
29
+ }
30
+ },
31
+ "telegram": {
32
+ "type": "object",
33
+ "properties": {
34
+ "bot_token": {
35
+ "type": "string"
36
+ },
37
+ "chat_id": {
38
+ "type": "string"
39
+ }
40
+ },
41
+ "required": ["chat_id", "bot_token"]
42
+ }
43
+ }
44
+ },
45
+ "template": {
46
+ "type": "object",
47
+ "properties": {
48
+ "path": {
49
+ "type": "string"
50
+ },
51
+ "cache": {
52
+ "type": "string"
53
+ }
54
+ }
55
+ },
56
+ "database": {
57
+ "type": "object",
58
+ "patternProperties": {
59
+ ".*": {
60
+ "type": "object",
61
+ "properties": {
62
+ "provider": {
63
+ "type": "string"
64
+ },
65
+ "user": {
66
+ "type": "string"
67
+ },
68
+ "password": {
69
+ "type": "string"
70
+ }
71
+ },
72
+ "required": ["provider"]
73
+ }
74
+ }
75
+ }
76
+ },
77
+ "id": "https://json.schemastore.org/csr",
78
+ "properties": {
79
+ "log": {
80
+ "$ref": "#/definitions/log"
81
+ },
82
+ "template": {
83
+ "$ref": "#/definitions/template"
84
+ },
85
+ "database": {
86
+ "$ref": "#/definitions/database"
87
+ }
88
+ },
89
+ "title": "CSR Framework schema",
90
+ "type": "object"
91
+ }
@@ -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:
@@ -12,11 +12,16 @@ functions:
12
12
  handler: handler.create
13
13
  events:
14
14
  - http:
15
- path: create
15
+ path: create/{username}
16
16
  method: post
17
17
  documentation:
18
18
  summary: Create User
19
19
  description: Creates a user and then sends a generated password email
20
+ tags:
21
+ - jesus
22
+ externalDocumentation:
23
+ url: https://bing.com
24
+ description: A link to bing
20
25
  requestBody:
21
26
  description: A user information object
22
27
  requestModels:
@@ -54,25 +59,30 @@ functions:
54
59
 
55
60
  custom:
56
61
  documentation:
62
+ description: This is a description of what this does
63
+ version: 1.0.0
57
64
  models:
58
65
  - name: ErrorResponse
59
66
  description: This is an error
60
- contentType: application/json
61
- schema: ${file(models/ErrorResponse.json)}
67
+ content:
68
+ application/json:
69
+ schema: ${file(../models/ErrorResponse.json)}
62
70
 
63
71
  - name: PutDocumentResponse
64
72
  description: PUT Document response model (external reference example)
65
- contentType: application/json
66
- schema: ${file(models/PutDocumentResponse.json)}
73
+ content:
74
+ application/json:
75
+ schema: ${file(../models/PutDocumentResponse.json)}
67
76
 
68
77
  - name: PutDocumentRequest
69
78
  description: PUT Document request model (inline example)
70
- contentType: application/json
71
- schema:
72
- $schema: http://json-schema.org/draft-04/schema#
73
- properties:
74
- SomeObject:
75
- type: object
79
+ content:
80
+ application/json:
81
+ schema:
82
+ $schema: http://json-schema.org/draft-04/schema#
76
83
  properties:
77
- SomeAttribute:
78
- type: string
84
+ SomeObject:
85
+ type: object
86
+ properties:
87
+ SomeAttribute:
88
+ type: string
@@ -0,0 +1,603 @@
1
+ 'use strict'
2
+
3
+ const fs = require('fs').promises
4
+ const path = require('path')
5
+ const sinon = require('sinon')
6
+ const $RefParser = require("@apidevtools/json-schema-ref-parser");
7
+ const expect = require('chai').expect
8
+
9
+ const serverlessMock = require('../helpers/serverless')
10
+ const DefinitionGenerator = require('../../src/definitionGenerator')
11
+
12
+ describe('DefinitionGenerator', () => {
13
+ let mockServerless
14
+ const v4 = new RegExp(/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i);
15
+ beforeEach(function() {
16
+ mockServerless = JSON.parse(JSON.stringify(serverlessMock))
17
+ });
18
+
19
+ describe('constructor', () => {
20
+ it('should return a definitionGenerator', function() {
21
+ const expected = new DefinitionGenerator({}, {})
22
+ expect(expected).to.be.an.instanceOf(DefinitionGenerator)
23
+ });
24
+
25
+ it('should default to version 3.0.0 of openAPI when openAPI version is not passed in', function() {
26
+ let expected = new DefinitionGenerator({}, {})
27
+ expect(expected.version).to.be.equal('3.0.0')
28
+
29
+ let serverlessObj = {
30
+ processedInput: {}
31
+ }
32
+ expected = new DefinitionGenerator(serverlessObj, {})
33
+ expect(expected.version).to.be.equal('3.0.0')
34
+
35
+ serverlessObj.processedInput = {
36
+ options: {}
37
+ }
38
+ expected = new DefinitionGenerator(serverlessObj, {})
39
+ expect(expected.version).to.be.equal('3.0.0')
40
+
41
+ serverlessObj.processedInput.options = {
42
+ test: 'abc'
43
+ }
44
+
45
+ expected = new DefinitionGenerator(serverlessObj, {})
46
+ expect(expected.version).to.be.equal('3.0.0')
47
+
48
+ serverlessObj.processedInput.options = {
49
+ openApiVersion: null
50
+ }
51
+
52
+ expected = new DefinitionGenerator(serverlessObj, {})
53
+ expect(expected.version).to.be.equal('3.0.0')
54
+
55
+ serverlessObj.processedInput.options = {
56
+ openApiVersion: undefined
57
+ }
58
+
59
+ expected = new DefinitionGenerator(serverlessObj, {})
60
+ expect(expected.version).to.be.equal('3.0.0')
61
+
62
+ serverlessObj.processedInput.options = {
63
+ openapiVersion: undefined
64
+ }
65
+
66
+ expected = new DefinitionGenerator(serverlessObj, {})
67
+ expect(expected.version).to.be.equal('3.0.0')
68
+ });
69
+
70
+ it('should respect the version of openAPI when passed in', function() {
71
+ let serverlessObj = {
72
+ processedInput: {
73
+ options: {
74
+ openApiVersion: '3.0.0'
75
+ }
76
+ }
77
+ }
78
+ let expected = new DefinitionGenerator(serverlessObj, {})
79
+ expect(expected.version).to.be.equal('3.0.0')
80
+
81
+ serverlessObj = {
82
+ processedInput: {
83
+ options: {
84
+ openApiVersion: '3.0.1'
85
+ }
86
+ }
87
+ }
88
+ expected = new DefinitionGenerator(serverlessObj, {})
89
+ expect(expected.version).to.be.equal('3.0.1')
90
+ });
91
+
92
+ it('should correctly resolve the RefParserOptions', async function() {
93
+ let expected = new DefinitionGenerator({}, {})
94
+ expect(expected.refParserOptions).to.be.an('object')
95
+ expect(expected.refParserOptions).to.be.empty
96
+
97
+ await fs.mkdir(path.resolve('options'))
98
+ .catch(err => {
99
+ console.error(err)
100
+ throw err
101
+ })
102
+
103
+ await fs.copyFile(path.resolve('test/helpers/ref-parser.js'), path.resolve('options/ref-parser.js'))
104
+ .catch(err => {
105
+ console.error(err)
106
+ throw err
107
+ })
108
+
109
+ expected = new DefinitionGenerator({}, {})
110
+ expect(expected.refParserOptions).to.be.an('object')
111
+ expect(expected.refParserOptions).to.have.property('continueOnError')
112
+
113
+ await fs.rm(path.resolve('options/ref-parser.js'))
114
+ .catch(err => {
115
+ console.error(err)
116
+ throw err
117
+ })
118
+
119
+ await fs.rmdir(path.resolve('options'))
120
+ .catch(err => {
121
+ console.error(err)
122
+ throw err
123
+ })
124
+ });
125
+ });
126
+
127
+ describe('createInfo', () => {
128
+ it('should create openAPI info object correctly', function() {
129
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
130
+ definitionGenerator.createInfo()
131
+
132
+ expect(definitionGenerator.openAPI).to.be.an('object')
133
+ expect(definitionGenerator.openAPI.info).to.be.an('object')
134
+ expect(definitionGenerator.openAPI.info).to.deep.equal(mockServerless.service.custom.documentation)
135
+ });
136
+
137
+ it('should use the service name when documentation title has not been supplied', function() {
138
+ delete mockServerless.service.custom.documentation.title
139
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
140
+ definitionGenerator.createInfo()
141
+
142
+ expect(definitionGenerator.openAPI).to.be.an('object')
143
+ expect(definitionGenerator.openAPI.info).to.be.an('object')
144
+ expect(definitionGenerator.openAPI.info.title).to.be.equal(mockServerless.service.service)
145
+ });
146
+
147
+ it('should use the service name when documentation description has not been supplied', function() {
148
+ delete mockServerless.service.custom.documentation.description
149
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
150
+ definitionGenerator.createInfo()
151
+
152
+ expect(definitionGenerator.openAPI).to.be.an('object')
153
+ expect(definitionGenerator.openAPI.info).to.be.an('object')
154
+ expect(definitionGenerator.openAPI.info.description).to.be.equal('')
155
+ });
156
+
157
+ it('should use an empty string when documentation description has not been supplied', function() {
158
+ delete mockServerless.service.custom.documentation.description
159
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
160
+ definitionGenerator.createInfo()
161
+
162
+ expect(definitionGenerator.openAPI).to.be.an('object')
163
+ expect(definitionGenerator.openAPI.info).to.be.an('object')
164
+ expect(definitionGenerator.openAPI.info.description).to.be.equal('')
165
+ });
166
+
167
+ it('should generate a uuid for version when documentation version has not been supplied', function() {
168
+ delete mockServerless.service.custom.documentation.version
169
+
170
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
171
+ definitionGenerator.createInfo()
172
+
173
+ expect(definitionGenerator.openAPI).to.be.an('object')
174
+ expect(definitionGenerator.openAPI.info).to.be.an('object')
175
+ expect(v4.test(definitionGenerator.openAPI.info.version)).to.be.true
176
+ });
177
+ });
178
+
179
+ describe('createTags', () => {
180
+ it('should add tags to the openAPI object correctly', function() {
181
+ mockServerless.service.custom.documentation.tags = [{name: 'tag1'}]
182
+
183
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
184
+ definitionGenerator.createTags()
185
+
186
+ expect(definitionGenerator.openAPI).to.be.an('object')
187
+ expect(definitionGenerator.openAPI.tags).to.be.an('array')
188
+ expect(definitionGenerator.openAPI.tags[0].name).to.be.equal('tag1')
189
+ });
190
+
191
+ it('should not add tags when they are not defined', function() {
192
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
193
+ expect(() => {
194
+ definitionGenerator.createTags()
195
+ }).to.throw()
196
+ });
197
+ });
198
+
199
+ describe('schemaCreator', () => {
200
+ describe('schemas that are objects', () => {
201
+ it('should add a simple schema to the components object', async function() {
202
+ const simpleSchema = {
203
+ type: 'string'
204
+ }
205
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
206
+ const expected = await definitionGenerator.schemaCreator(simpleSchema, 'simpleSchema')
207
+ .catch((err) => {
208
+ console.error(err)
209
+ })
210
+
211
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('simpleSchema')
212
+ expect(JSON.stringify(definitionGenerator.openAPI.components.schemas.simpleSchema)).to.equal(JSON.stringify(simpleSchema))
213
+ expect(expected).to.equal('#/components/schemas/simpleSchema')
214
+ });
215
+
216
+ it('should add a complex schema to the components object', async function() {
217
+ const complexSchema = {
218
+ type: 'object',
219
+ properties: {
220
+ error: {
221
+ type: 'string'
222
+ }
223
+ }
224
+ }
225
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
226
+ const expected = await definitionGenerator.schemaCreator(complexSchema, 'main')
227
+ .catch((err) => {
228
+ console.error(err)
229
+ })
230
+
231
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('main')
232
+ expect(JSON.stringify(definitionGenerator.openAPI.components.schemas.main)).to.equal(JSON.stringify(complexSchema))
233
+ expect(expected).to.equal('#/components/schemas/main')
234
+ });
235
+
236
+ it('should add each definition of a complex schema to the components object', async function() {
237
+ const complexSchema = {
238
+ "$schema": "http://json-schema.org/draft-04/schema#",
239
+ "title": "JSON API Schema",
240
+ "description": "This is a blah blah for responses in the JSON API format. For more, see http://jsonapi.org",
241
+ "type": "object",
242
+ "required": [
243
+ "errors"
244
+ ],
245
+ "properties": {
246
+ "errors": {
247
+ "type": "array",
248
+ "items": {
249
+ "$ref": "#/definitions/error"
250
+ },
251
+ "uniqueItems": true
252
+ }
253
+ },
254
+ "definitions": {
255
+ "error": {
256
+ "type": "object",
257
+ "properties": {
258
+ "id": {
259
+ "description": "A unique identifier for this particular occurrence of the problem.",
260
+ "type": "string"
261
+ }
262
+ }
263
+ }
264
+ }
265
+ }
266
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
267
+ const expected = await definitionGenerator.schemaCreator(complexSchema, 'PutRequest')
268
+ .catch((err) => {
269
+ console.error(err)
270
+ })
271
+
272
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
273
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
274
+ expect(expected).to.equal('#/components/schemas/PutRequest')
275
+ });
276
+
277
+ it(`should not overwrite an object that already exists in the components if they're the same`, async function() {
278
+ const complexSchema = {
279
+ "$schema": "http://json-schema.org/draft-04/schema#",
280
+ "title": "JSON API Schema",
281
+ "description": "This is a blah blah for responses in the JSON API format. For more, see http://jsonapi.org",
282
+ "type": "object",
283
+ "required": [
284
+ "errors"
285
+ ],
286
+ "properties": {
287
+ "errors": {
288
+ "type": "array",
289
+ "items": {
290
+ "$ref": "#/definitions/error"
291
+ },
292
+ "uniqueItems": true
293
+ }
294
+ },
295
+ "definitions": {
296
+ "error": {
297
+ "type": "object",
298
+ "properties": {
299
+ "id": {
300
+ "description": "A unique identifier for this particular occurrence of the problem.",
301
+ "type": "string"
302
+ }
303
+ }
304
+ }
305
+ }
306
+ }
307
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
308
+ let expected = await definitionGenerator.schemaCreator(complexSchema, 'PutRequest')
309
+ .catch((err) => {
310
+ console.error(err)
311
+ })
312
+
313
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
314
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
315
+ expect(expected).to.equal('#/components/schemas/PutRequest')
316
+
317
+ expected = await definitionGenerator.schemaCreator(complexSchema, 'PutRequest')
318
+ .catch((err) => {
319
+ console.error(err)
320
+ })
321
+
322
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
323
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
324
+ expect(expected).to.equal('#/components/schemas/PutRequest')
325
+ });
326
+
327
+ it(`should create a new object for a similarly named object but with different properties`, async function() {
328
+ const complexSchema = {
329
+ "$schema": "http://json-schema.org/draft-04/schema#",
330
+ "title": "JSON API Schema",
331
+ "description": "This is a blah blah for responses in the JSON API format. For more, see http://jsonapi.org",
332
+ "type": "object",
333
+ "required": [
334
+ "errors"
335
+ ],
336
+ "properties": {
337
+ "errors": {
338
+ "type": "array",
339
+ "items": {
340
+ "$ref": "#/definitions/error"
341
+ },
342
+ "uniqueItems": true
343
+ }
344
+ },
345
+ "definitions": {
346
+ "error": {
347
+ "type": "object",
348
+ "properties": {
349
+ "id": {
350
+ "description": "A unique identifier for this particular occurrence of the problem.",
351
+ "type": "string"
352
+ }
353
+ }
354
+ }
355
+ }
356
+ }
357
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
358
+ let expected = await definitionGenerator.schemaCreator(complexSchema, 'PutRequest')
359
+ .catch((err) => {
360
+ console.error(err)
361
+ })
362
+
363
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
364
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
365
+ expect(expected).to.equal('#/components/schemas/PutRequest')
366
+
367
+ complexSchema.properties.cheese = {
368
+ type: 'string'
369
+ }
370
+
371
+ expected = await definitionGenerator.schemaCreator(complexSchema, 'PutRequest')
372
+ .catch((err) => {
373
+ console.error(err)
374
+ })
375
+
376
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
377
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
378
+
379
+ let newSchemaStr = expected.split('/')
380
+ expect(v4.test(newSchemaStr[newSchemaStr.length-1].split('PutRequest-')[1])).to.be.true
381
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property(newSchemaStr[newSchemaStr.length-1])
382
+
383
+ // expected = await definitionGenerator.schemaCreator(complexSchema, 'PutRequest')
384
+ // .catch((err) => {
385
+ // console.error(err)
386
+ // })
387
+
388
+ // expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
389
+ // expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
390
+ // console.log(expected)
391
+ // expect(expected)
392
+ // expect(expected).to.equal('#/components/schemas/PutRequest1')
393
+
394
+ complexSchema.properties.wine = {
395
+ type: 'string'
396
+ }
397
+
398
+ expected = await definitionGenerator.schemaCreator(complexSchema, 'PutRequest')
399
+ .catch((err) => {
400
+ console.error(err)
401
+ })
402
+
403
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
404
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
405
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property(newSchemaStr[newSchemaStr.length-1])
406
+ newSchemaStr = expected.split('/')
407
+ expect(v4.test(newSchemaStr[newSchemaStr.length-1].split('PutRequest-')[1])).to.be.true
408
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property(newSchemaStr[newSchemaStr.length-1])
409
+ });
410
+
411
+ it(`should create a new object for a differently named object but with same properties`, async function() {
412
+ const complexSchema = {
413
+ "$schema": "http://json-schema.org/draft-04/schema#",
414
+ "title": "JSON API Schema",
415
+ "description": "This is a blah blah for responses in the JSON API format. For more, see http://jsonapi.org",
416
+ "type": "object",
417
+ "required": [
418
+ "errors"
419
+ ],
420
+ "properties": {
421
+ "errors": {
422
+ "type": "array",
423
+ "items": {
424
+ "$ref": "#/definitions/error"
425
+ },
426
+ "uniqueItems": true
427
+ }
428
+ },
429
+ "definitions": {
430
+ "error": {
431
+ "type": "object",
432
+ "properties": {
433
+ "id": {
434
+ "description": "A unique identifier for this particular occurrence of the problem.",
435
+ "type": "string"
436
+ }
437
+ }
438
+ }
439
+ }
440
+ }
441
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
442
+ let expected = await definitionGenerator.schemaCreator(complexSchema, 'PutRequest')
443
+ .catch((err) => {
444
+ console.error(err)
445
+ })
446
+
447
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
448
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
449
+ expect(expected).to.equal('#/components/schemas/PutRequest')
450
+
451
+ expected = await definitionGenerator.schemaCreator(complexSchema, 'ContactPutRequest')
452
+ .catch((err) => {
453
+ console.error(err)
454
+ })
455
+
456
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
457
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
458
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('ContactPutRequest')
459
+ expect(expected).to.equal('#/components/schemas/ContactPutRequest')
460
+ });
461
+
462
+ it('should not create an object that already references schemas in components', async function() {
463
+ const simpleSchema = {
464
+ "$schema": "http://json-schema.org/draft-04/schema#",
465
+ "title": "JSON API Schema",
466
+ "description": "This is a blah blah for responses in the JSON API format. For more, see http://jsonapi.org",
467
+ "type": "object",
468
+ "properties": {
469
+ "meta": {
470
+ "type": "string",
471
+
472
+ }
473
+ }
474
+ }
475
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
476
+ let expected = await definitionGenerator.schemaCreator(simpleSchema, 'meta')
477
+ .catch((err) => {
478
+ console.error(err)
479
+ })
480
+
481
+ expect(expected).to.equal('#/components/schemas/meta')
482
+
483
+ const complexSchema = {
484
+ "$schema": "http://json-schema.org/draft-04/schema#",
485
+ "title": "JSON API Schema",
486
+ "description": "This is a blah blah for responses in the JSON API format. For more, see http://jsonapi.org",
487
+ "type": "object",
488
+ "required": [
489
+ "errors"
490
+ ],
491
+ "properties": {
492
+ "errors": {
493
+ "type": "array",
494
+ "items": {
495
+ "$ref": "#/definitions/error"
496
+ },
497
+ "uniqueItems": true
498
+ },
499
+ "meta": {
500
+ "$ref": "#/definitions/meta"
501
+ }
502
+ },
503
+ "definitions": {
504
+ "error": {
505
+ "type": "object",
506
+ "properties": {
507
+ "id": {
508
+ "description": "A unique identifier for this particular occurrence of the problem.",
509
+ "type": "string"
510
+ }
511
+ }
512
+ }
513
+ }
514
+ }
515
+
516
+ expected = await definitionGenerator.schemaCreator(complexSchema, 'PutRequest')
517
+ .catch((err) => {
518
+ console.error(err)
519
+ })
520
+
521
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('PutRequest')
522
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('error')
523
+ expect(expected).to.equal('#/components/schemas/PutRequest')
524
+ });
525
+ });
526
+
527
+ describe('schemas that are urls', () => {
528
+ it('should attempt to download a schema and convert it', async function() {
529
+ const simpleSchema = 'https:///google.com/build/LicensedMember.json'
530
+ const LicensedMemberJSON = require('../json/complex.json')
531
+
532
+ const stub = sinon.stub($RefParser, 'dereference').resolves(LicensedMemberJSON)
533
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
534
+ const expected = await definitionGenerator.schemaCreator(simpleSchema, 'LicensedMember')
535
+ .catch((err) => {
536
+ console.error(err)
537
+ })
538
+
539
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('LicensedMember')
540
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('log')
541
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('template')
542
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('database')
543
+ expect(expected).to.equal('#/components/schemas/LicensedMember')
544
+
545
+ stub.restore()
546
+ });
547
+
548
+ it('should take a mix of schemas', async function() {
549
+ const complexSchema = 'https:///google.com/build/LicensedMember.json'
550
+ const LicensedMemberJSON = require('../json/complex.json')
551
+
552
+ const stub = sinon.stub($RefParser, 'dereference').resolves(LicensedMemberJSON)
553
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
554
+ let expected = await definitionGenerator.schemaCreator(complexSchema, 'LicensedMember')
555
+ .catch((err) => {
556
+ console.error(err)
557
+ })
558
+
559
+ const simpleSchema = {
560
+ type: "object",
561
+ properties: {
562
+ UUID: {
563
+ $ref: "#/definitions/log"
564
+ },
565
+ name: {
566
+ type: "string"
567
+ }
568
+ },
569
+ definitions: {}
570
+ }
571
+
572
+ expected = await definitionGenerator.schemaCreator(simpleSchema, 'simpleSchema')
573
+ .catch((err) => {
574
+ console.error(err)
575
+ })
576
+
577
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('LicensedMember')
578
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('log')
579
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('template')
580
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('database')
581
+ expect(definitionGenerator.openAPI.components.schemas).to.have.property('simpleSchema')
582
+ expect(expected).to.equal('#/components/schemas/simpleSchema')
583
+
584
+ stub.restore()
585
+ });
586
+
587
+ it('should throw an error when a url can not be resolved', async function() {
588
+ const simpleSchema = 'https:///google.com/build/LicensedMember.json'
589
+
590
+ const stub = sinon.stub($RefParser, 'dereference').rejects(new Error())
591
+ const definitionGenerator = new DefinitionGenerator(mockServerless)
592
+ const expected = await definitionGenerator.schemaCreator(simpleSchema, 'simpleSchema')
593
+ .catch((err) => {
594
+ console.error(err)
595
+ })
596
+
597
+ expect(expected).to.be.undefined
598
+
599
+ stub.restore()
600
+ });
601
+ });
602
+ });
603
+ });
@@ -0,0 +1,10 @@
1
+ 'use strict'
2
+
3
+ const sinon = require('sinon')
4
+ const expect = require('chai').expect
5
+
6
+ const OpenAPIGenerator = require('../../src/openAPIGenerator')
7
+
8
+ xdescribe('OpenAPIGenerator', () => {
9
+
10
+ });