serverless-openapi-documenter 0.0.50 → 0.0.52
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 +27 -0
- package/package.json +1 -1
- package/src/definitionGenerator.js +86 -6
package/README.md
CHANGED
|
@@ -295,12 +295,22 @@ custom:
|
|
|
295
295
|
contentType: "application/json"
|
|
296
296
|
schema:
|
|
297
297
|
$schema: "http://json-schema.org/draft-04/schema#"
|
|
298
|
+
type: object
|
|
298
299
|
properties:
|
|
299
300
|
SomeObject:
|
|
300
301
|
type: "object"
|
|
301
302
|
properties:
|
|
302
303
|
SomeAttribute:
|
|
303
304
|
type: "string"
|
|
305
|
+
examples:
|
|
306
|
+
- name: someObjectInlineExample
|
|
307
|
+
summary: an example of a request
|
|
308
|
+
description: a longer string than the summary
|
|
309
|
+
value: {SomeObject: {SomeAttribute: 'attribute'}}
|
|
310
|
+
- name: someObjectExternalExample
|
|
311
|
+
summary: an example of a request external
|
|
312
|
+
description: a longer string than the summary
|
|
313
|
+
externalValue: https://example.com/external.json
|
|
304
314
|
```
|
|
305
315
|
|
|
306
316
|
The Second way of writing the models:
|
|
@@ -329,12 +339,22 @@ custom:
|
|
|
329
339
|
application/json:
|
|
330
340
|
schema:
|
|
331
341
|
$schema: "http://json-schema.org/draft-04/schema#"
|
|
342
|
+
type: object
|
|
332
343
|
properties:
|
|
333
344
|
SomeObject:
|
|
334
345
|
type: "object"
|
|
335
346
|
properties:
|
|
336
347
|
SomeAttribute:
|
|
337
348
|
type: "string"
|
|
349
|
+
examples:
|
|
350
|
+
- name: someObjectInlineExample
|
|
351
|
+
summary: an example of a request
|
|
352
|
+
description: a longer string than the summary
|
|
353
|
+
value: {SomeObject: {SomeAttribute: 'attribute'}}
|
|
354
|
+
- name: someObjectExternalExample
|
|
355
|
+
summary: an example of a request external
|
|
356
|
+
description: a longer string than the summary
|
|
357
|
+
externalValue: https://example.com/external.json
|
|
338
358
|
```
|
|
339
359
|
|
|
340
360
|
##### Model re-use
|
|
@@ -403,6 +423,7 @@ functions:
|
|
|
403
423
|
- http:
|
|
404
424
|
path: create
|
|
405
425
|
method: post
|
|
426
|
+
cors: true
|
|
406
427
|
summary:
|
|
407
428
|
documentation:
|
|
408
429
|
summary: "Create User"
|
|
@@ -645,6 +666,12 @@ responseHeaders:
|
|
|
645
666
|
type: integer
|
|
646
667
|
```
|
|
647
668
|
|
|
669
|
+
###### CORS
|
|
670
|
+
|
|
671
|
+
You can automatically generate CORS response headers by setting `cors` at the function level. Serverless allows you to modify how CORS is setup, so you can have the default options with `cors: true`, or you can modify the settings as shown in the [serverless documentation for CORS](https://www.serverless.com/framework/docs/providers/aws/events/apigateway#enabling-cors).
|
|
672
|
+
|
|
673
|
+
The generator will interpret your settings for CORS and automatically add the response headers. If for whatever reason you wish to override these, you can set them via the above `responseHeaders` setting and it'll apply your overrides.
|
|
674
|
+
|
|
648
675
|
## Example configuration
|
|
649
676
|
|
|
650
677
|
Please view the example [serverless.yml](test/serverless-tests/serverless%202/serverless.yml).
|
package/package.json
CHANGED
|
@@ -35,6 +35,24 @@ class DefinitionGenerator {
|
|
|
35
35
|
securitySchemes: 'securitySchemes'
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
this.DEFAULT_CORS_HEADERS = {
|
|
39
|
+
'Access-Control-Allow-Origin': {
|
|
40
|
+
description: 'The Access-Control-Allow-Origin response header indicates whether the response can be shared with requesting code from the given origin.',
|
|
41
|
+
schema: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
default: '*',
|
|
44
|
+
example: 'https://developer.mozilla.org'
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
'Access-Control-Allow-Credentials': {
|
|
48
|
+
description: `The Access-Control-Allow-Credentials response header tells browsers whether to expose the response to the frontend JavaScript code when the request's credentials mode (Request.credentials) is include`,
|
|
49
|
+
schema: {
|
|
50
|
+
type: 'boolean',
|
|
51
|
+
default: true
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
38
56
|
try {
|
|
39
57
|
this.refParserOptions = require(path.resolve('options', 'ref-parser.js'))
|
|
40
58
|
} catch (err) {
|
|
@@ -123,6 +141,7 @@ class DefinitionGenerator {
|
|
|
123
141
|
for (const httpFunction of httpFunctions) {
|
|
124
142
|
for (const event of httpFunction.event) {
|
|
125
143
|
if (event?.http?.documentation || event?.httpApi?.documentation) {
|
|
144
|
+
this.currentEvent = event?.http || event?.httpApi
|
|
126
145
|
const documentation = event?.http?.documentation || event?.httpApi?.documentation
|
|
127
146
|
|
|
128
147
|
this.currentFunctionName = httpFunction.functionInfo.name
|
|
@@ -328,14 +347,68 @@ class DefinitionGenerator {
|
|
|
328
347
|
})
|
|
329
348
|
}
|
|
330
349
|
|
|
350
|
+
|
|
351
|
+
const corsHeaders = await this.corsHeaders()
|
|
352
|
+
.catch(err => {
|
|
353
|
+
throw err;
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
if (obj.headers) {
|
|
357
|
+
for (const key in corsHeaders) {
|
|
358
|
+
if (!(key in obj.headers) && (obj.headers[key] = {})) {
|
|
359
|
+
obj.headers[key] = corsHeaders[key]
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
} else {
|
|
363
|
+
obj.headers = corsHeaders
|
|
364
|
+
}
|
|
365
|
+
|
|
331
366
|
Object.assign(responses,{[response.statusCode]: obj})
|
|
332
367
|
}
|
|
333
368
|
|
|
334
369
|
return responses
|
|
335
370
|
}
|
|
336
371
|
|
|
372
|
+
async corsHeaders() {
|
|
373
|
+
let headers = {}
|
|
374
|
+
if (this.currentEvent?.cors === true) {
|
|
375
|
+
headers = await this.createResponseHeaders(this.DEFAULT_CORS_HEADERS)
|
|
376
|
+
.catch(err => {
|
|
377
|
+
throw err;
|
|
378
|
+
})
|
|
379
|
+
} else if (this.currentEvent.cors) {
|
|
380
|
+
const newHeaders = {}
|
|
381
|
+
for (const key of Object.keys(this.DEFAULT_CORS_HEADERS)) {
|
|
382
|
+
if (key === 'Access-Control-Allow-Credentials' &&
|
|
383
|
+
this.currentEvent.cors.allowCredentials === undefined || this.currentEvent.cors?.allowCredentials === false) {
|
|
384
|
+
continue
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const obj = JSON.parse(JSON.stringify(this.DEFAULT_CORS_HEADERS[key]))
|
|
388
|
+
|
|
389
|
+
if (key === 'Access-Control-Allow-Origin') {
|
|
390
|
+
if (this.currentEvent.cors?.origins || this.currentEvent.cors?.origin) {
|
|
391
|
+
obj.schema.example = this.currentEvent.cors?.origins?.toString() || this.currentEvent.cors?.origin?.toString()
|
|
392
|
+
} else if (this.currentEvent.cors?.allowedOrigins) {
|
|
393
|
+
obj.schema.example = this.currentEvent.cors.allowedOrigins.toString()
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
Object.assign(newHeaders, {[key]: obj})
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
headers = await this.createResponseHeaders(newHeaders)
|
|
401
|
+
.catch(err => {
|
|
402
|
+
throw err;
|
|
403
|
+
})
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return headers;
|
|
407
|
+
}
|
|
408
|
+
|
|
337
409
|
async createResponseHeaders(headers) {
|
|
338
410
|
const obj = {}
|
|
411
|
+
|
|
339
412
|
for (const header of Object.keys(headers)) {
|
|
340
413
|
const newHeader = {}
|
|
341
414
|
newHeader.description = headers[header].description || ''
|
|
@@ -385,16 +458,22 @@ class DefinitionGenerator {
|
|
|
385
458
|
}
|
|
386
459
|
const obj = {}
|
|
387
460
|
|
|
388
|
-
if (mediaTypeDocumentation.example)
|
|
389
|
-
obj.example = mediaTypeDocumentation.example
|
|
390
|
-
|
|
391
|
-
if (mediaTypeDocumentation.examples)
|
|
392
|
-
obj.examples = this.createExamples(mediaTypeDocumentation.examples)
|
|
393
|
-
|
|
394
461
|
let schema
|
|
395
462
|
if (mediaTypeDocumentation?.content) {
|
|
463
|
+
if (mediaTypeDocumentation.content[contentKey]?.example)
|
|
464
|
+
obj.example = mediaTypeDocumentation.content[contentKey].example
|
|
465
|
+
|
|
466
|
+
if (mediaTypeDocumentation.content[contentKey]?.examples)
|
|
467
|
+
obj.examples = this.createExamples(mediaTypeDocumentation.content[contentKey].examples)
|
|
468
|
+
|
|
396
469
|
schema = mediaTypeDocumentation.content[contentKey].schema
|
|
397
470
|
} else if (mediaTypeDocumentation?.contentType && mediaTypeDocumentation.schema) {
|
|
471
|
+
if (mediaTypeDocumentation?.example)
|
|
472
|
+
obj.example = mediaTypeDocumentation.example
|
|
473
|
+
|
|
474
|
+
if (mediaTypeDocumentation?.examples)
|
|
475
|
+
obj.examples = this.createExamples(mediaTypeDocumentation.examples)
|
|
476
|
+
|
|
398
477
|
schema = mediaTypeDocumentation.schema
|
|
399
478
|
}
|
|
400
479
|
|
|
@@ -675,6 +754,7 @@ class DefinitionGenerator {
|
|
|
675
754
|
|
|
676
755
|
for(const example of examples) {
|
|
677
756
|
Object.assign(examplesObj, {[example.name]: example})
|
|
757
|
+
delete examplesObj[example.name].name
|
|
678
758
|
}
|
|
679
759
|
|
|
680
760
|
return examplesObj;
|